David T.
David T.

Reputation: 23371

Concurrent writes to different properties of GAE Datastore Entity

I'm using Google Appengine in Java flavor, and i'm trying to do the following:

1 - create an entity with property COUNT as 0.

2a - kick off a task queue task that does some network call, and updates a STATUS property for this same entity (using Datastore#put)

2b - meanwhile, in the original "thread", save a different number for COUNT. (also using Datastore#put)

given that 2a and 2b may finish in parallel at the exact same moment, but they update two different properties (STATUS and COUNT), would these ever conflict or throw like a concurrent modification exception?

Upvotes: 1

Views: 243

Answers (1)

Dan Cornilescu
Dan Cornilescu

Reputation: 39824

As Igor Artamonov commented, changing just one property of an entity still requires re-writing the entire entity. With this in mind you're looking at 2 entity writes which would have to be done inside transactions to prevent overwriting each-other.

The flow you describe will cause transaction collisions if the transaction associated with the task enqueud in 2a starts before the 2b transaction is committed.

The 2a task execution is delayed - it'll be a request hitting you app at a later moment (the actual delay depending on your app's load at the moment and its scalability config). It can be a lot longer than the 2b execution. Or it could be tiny, allowing 2a to start before 2b ends.

I'd recommend changing the order of the ops to make it more predictable and, as a side effect, minimize the chances of transaction collisions/retries:

  • on the current request thread perform 2b (in a transaction)
  • in the same transaction transactionally enqueue the 2a task, which should happen only after 2b is successful. Otherwise you need to take care of potentially enqueueing multiple 2a tasks during 2b retries.

Upvotes: 1

Related Questions