mosceo
mosceo

Reputation: 1224

Transactions in NDB don't include the method's arguments

It seems to me that a transaction in a method does not include the variables that are the arguments of the method. Because in my application I get the entity incremented without changes of the other models.

@ndb.transactional(xg=true)
def method(entity):
    # `entity` is a datastore entity

    # Transaction works here
    Model.foo()
    # ...here too
    Model.bar()

    # But not here! Always incremented.
    entity.x += 1
    entity.put()

In the example above the property x of the entity will be incremented even if the transaction fails.

Is it correct?

Upvotes: 1

Views: 346

Answers (1)

dragonx
dragonx

Reputation: 15143

Yes. Since the entity get() was outside the transaction, there's no value to to roll back to (the transaction wouldn't know the previous value of entity. Also, if this transaction was actually intended to increment entity.x by one, it would fail to provide transactional consistency.

Imagine entity.x = 1, this transaction could potentially start, and a second request operating on the same request could run at the same time. Since both gets are outside of the transaction, they'll both read 1, then they'll both increment x to 2, and it'll save as 2, even though it was incremented twice and should be 3. Since the get() was outside the transaction, it would not be protected.

Upvotes: 3

Related Questions