will a read-only datastore transaction fail on commit if the entity group is modified during the transaction?

88 views
Skip to first unread message

AndyD

unread,
Jan 24, 2012, 10:48:18 AM1/24/12
to google-a...@googlegroups.com
Example case:

time 0: transaction A begins
time 1: transaction B begins
time 2: transaction A reads entity 123
time 3: transaction B writes entity 123 (or entity 456, in the same entity group as 123)
time 4: transaction B is committed
time 5: transaction A is committed

There are no write operations in transaction A.  Does the commit of A fail with a ConcurrentModificationException?  

-AndyD

Moe

unread,
Oct 23, 2012, 10:49:31 AM10/23/12
to google-a...@googlegroups.com
Hi Andy, strange that nobody replied to this question up to now. I was wondering the same thing, until I read in the docs:

Finally, you can use a transaction to read a consistent snapshot of the Datastore. This can be useful when multiple reads are needed to render a page or export data that must be consistent. These kinds of transactions are often called read-only transactions, since they perform no writes. Read-only single-group transactions never fail due to concurrent modifications, so you don't have to implement retries upon failure. However, XG transactions can fail due to concurrent modifications, so these should have retries. Committing and rolling back a read-only transaction are both no-ops.

(source: https://developers.google.com/appengine/docs/java/datastore/transactions)

But, I still wonder how this is achieved. I thought that optimistic concurrency works like this:
- when we enter a transaction a timestamp is associated to the transaction.
- when we commit a transaction, the timestamp is compared with the modification timestamps of all "touched" entities in our transaction
- if there are entities which have a newer timestamp than the one of the transaction, the transaction fails

It seems that the Google datastore somehow achieves to freeze the datastore, so there is no conflict when another transaction modifies your data while you read it. However, if both transactions modify an entity, this is a conflict and the second transaction won't commit. My question: how is it technically achieved to look at a "freezed" version of the datastore from the point of view of a transaction?

Andrew Mackenzie

unread,
Oct 23, 2012, 5:13:28 PM10/23/12
to google-a...@googlegroups.com
After reading the documentation that, yes you will get an exception (or if it is the write that has arrived "late" then it will get the exception on committing...) - otherwise, what would be the point of using an exception around any data store reads?

AndyD

unread,
Oct 24, 2012, 8:22:21 AM10/24/12
to google-a...@googlegroups.com


On Tuesday, October 23, 2012 5:13:28 PM UTC-4, Andrew Mackenzie wrote:
After reading the documentation that, yes you will get an exception (or if it is the write that has arrived "late" then it will get the exception on committing...) - otherwise, what would be the point of using an exception around any data store reads?

I'm not positive, but I doubt the write transaction ("B" above) would get an exception if it committed last, since the read transaction didn't write anything.  The point of using a read transaction is to get a consistent view of the data store over the course of multiple reads, instead of getting the state as each individual read is made.
Reply all
Reply to author
Forward
0 new messages