If you need strong consistency guarantees across network requests, you are going to need to do a bit of extra work, since the datastore's transactions only work within a single request. To make this concrete:
1A Client A request: Read Work key "foo", send it to the browser.
1B Client B request: Read Work key "foo", send it to the browser
2A Client B request: Read work, Update Work setting property "something" to 42.
2B Client A request: Read work, Update work, setting property "other" to False
If 2A and 2B are being processed at the same time, then *one of* the operations will get applied, overwriting the other. That mean you will see "something=42" OR "other=False", while you probably want BOTH to be applied.
If you need real transactions "across" network requests (e.g. out to a client browser) then you will need to implement something on top of what is provided by the database. At a high level, I've seen people take three approaches:
1. Optimistic: assume everything will be fine, but verify if there have been any updates. You can do this by keeping a "version" property that you increment on each update. When the client request comes back, it must include the version of the object it was editing. If the current version is not the same, you can reject the update.
2. Pessimistic: When clients start an edit, they can acquire a "lease", which is a lock with a time limit. You add a "locked_until" property to your entity. Any other client cannot make the update until this time. Ticketmaster and airlines use this approach when you are purchasing tickets.
3. Merge edits: In some cases, if the client request contains fine-grained edits, and the edits don't conflict, you might be able to merge them. This is much more difficult to implement though, and tends to be very application specific. Google docs and git use this approach.
I hope this helps! Also to be clear: this is not a datastore-specific issue, this happens with all data storage systems, including traditional relational databases.
Evan