Is a re-tried transation after transaction collision safe?
Can a failed — with "transaction collision" — write operation to an entity overwrite changes made to the same entity on the other successfully committed transaction?
I understand that transactional operations in gae are in snapshot SERIALIZABLE isolation, but it's not clear if write skew is possible.
For simplicity sake a bad example of doing counters:
def increment_counter(key, amount):
obj = db.get(key)
obj.counter += amount
obj.put()
If run in transaction, failed due a collision and re-tried, will it update correctly?
Does retry mean a whole operation gets re-tried or just the commit, or does it mean that collision was on the entity group, but the change made here is not in conflict with other changes in the entity group — 开发者_如何转开发cause they where made to different entities.
PS. This maybe a dumb question, but it bugs me how exactly these re-tries are applied.
UPDATE
In the Transactions article is a clue that I missed.
If the entity is updated during the transaction, then the transaction is retried until all steps are completed without interruption
Does this mean that the whole code run in the transaction context is re-run after a collision?
Yes, the whole function is re-run in the event of a collision. This is the reason you have to implement transactions in their own functions: because they may need to be executed multiple times. It's guaranteed that your transactional changes won't overwrite other transactional changes - that's the whole point of having transactionality.
精彩评论