Reputation: 2263
I need only confirmation that I get this right.
If, for example I have an Entity X
with a field x
, and when a request is sent I want to do X.x++
. If I use just X = ofy().load().type(X.class).id(xId).get()
then I do some calculations and afterwards I do X.x++
and the I save it. If during the calculations another request is posted, I'll get an unwanted behavior. And instead if I'll do this all in a transaction, the second request won't have access to X
until I finish.
Is it so?
Sorry if the question is a bit nooby.
Thanks, Dan
Upvotes: 1
Views: 967
Reputation: 16825
Yes you got it right but when using transaction remember the first that completes wins and the rest fail. Look also at @Peter Knego's answer for how they work.
But don't worry about the second request if it fails to read. You have like 2 options:
As far as the retries are concerned:
Your transaction function can be called multiple times safely without undesirable side effects. If this is not possible, you can set retries=0, but know that the transaction will fail on the first incident of contention
Example:
@db.transactional(retries=10)
As far as eventual consistency is concerned:
You can opt out of this protection by specifying a read policy that requests eventual consistency. With an eventually consistent read of an entity, your app gets the current known state of the entity being read, regardless of whether there are still committed changes to be applied. With an eventually consistent ancestor query, the indexes used for the query are consistent with the time the indexes are read from disk. In other words, an eventual consistency read policy causes gets and queries to behave as if they are not a part of the current transaction. This may be faster in some cases, since the operations do not have to wait for committed changes to be written before returning a result.
Example:
@db.transactional()
def test():
game_version = db.get(
db.Key.from_path('GameVersion', 1),
read_policy=db.EVENTUAL_CONSISTENCY)
Upvotes: 2
Reputation: 80330
No, GAE transaction do not do locking, they use optimistic concurrency control. You will have access to X
all the time, but when you try to save it in the second transactions it will fail with ConcurrentModificationException
.
Upvotes: 2