问题
I have lots of views manipulating entities of same kind:
def view1(request, key):
user = ndb.Key(urlsafe=key).get()
user.x = 1
user.put()
...
def view2(request, key):
user = ndb.Key(urlsafe=key).get()
user.y = 2
user.put()
...
Obviously, this is error-prone due to possible race conditions (last wins):
- view1 reads whole user entity data (x=None, y=None)
- view2 reads whole user entity data (x=None, y=None)
- view1
user.x = 1
(x=1, y=None) - view2
user.y = 2
(x=None, y=2) - view1
user.put()
(x=1, y=None) - view2
user.put()
(x=None, y=2)
What are best ways to fix this and what behaviour is considered most decent? Transactions (one of the requests is gonna fail, is this ok)?
回答1:
Wrap your get and put into a transaction. This will ensure you cannot stomp over a different update.
You can read more about transactions with the NDB Client Library documentation.
In your code, you could for example just use the NDB transaction decorator:
@ndb.transactional(retries=1)
def view1(request, key):
user = ndb.Key(urlsafe=key).get()
user.x = 1
user.put()
...
@ndb.transactional(retries=1)
def view2(request, key):
user = ndb.Key(urlsafe=key).get()
user.y = 2
user.put()
来源:https://stackoverflow.com/questions/38955748/cloud-datastore-ways-to-avoid-race-conditions