Inconsistent transaction behavior in local Appengine data warehouse?

Appengine docs talk about data warehouse transactions: http://code.google.com/appengine/docs/java/datastore/transactions.html#Isolation_and_Consistency

In a transaction, all reads reflect the current, consistent state of the Datastore at the time the transaction started. This does not include previous puts and deletes inside the transaction. Queries and gets inside a transaction are guaranteed to see a single, consistent snapshot of the Datastore as of the beginning of the transaction. 

With that in mind, I created the following two unit tests to test this (against local data storage). I would expect both of my tests below to pass. However, only "test1" passes, while "test2" fails. The only difference is fixing tx1 in "test1".

Is this a mistake in the local data warehouse, a misunderstanding of GAE documents, or an error in my unit tests? Or something else?

Thanks!

 @Test(expected = EntityNotFoundException.class) public void test1() throws EntityNotFoundException { DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); // Create 2 Transactions... Transaction txn1 = datastore.beginTransaction(); Transaction txn2 = datastore.beginTransaction(); try { Key entityWithStringKey = KeyFactory.createKey("TestEntity", "test"); Entity entityWithString = new Entity(entityWithStringKey); datastore.put(txn1, entityWithString); entityWithString = datastore.get(txn2, entityWithStringKey); // The above should throw EntityNotFoundException assertNull(entityWithString); } finally { if (txn1.isActive()) { txn1.rollback(); } if (txn2.isActive()) { txn2.rollback(); } } @Test(expected = EntityNotFoundException.class) public void test2() throws EntityNotFoundException { DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); // Create 2 Transactions... Transaction txn1 = datastore.beginTransaction(); Transaction txn2 = datastore.beginTransaction(); Key entityWithStringKey = KeyFactory.createKey("TestEntity", "test"); try { Entity entityWithString = new Entity(entityWithStringKey); datastore.put(txn1, entityWithString); txn1.commit(); } finally { if (txn1.isActive()) { txn1.rollback(); } } try { Entity entityWithString = datastore.get(txn2, entityWithStringKey); assertNull(entityWithString); // The above should throw EntityNotFoundException } finally { if (txn2.isActive()) { txn2.rollback(); } } } 
+4
source share
1 answer

I suspect that the transaction does not actually start when you call datastore.beginTransaction - it starts when the transaction first enters the database - this will be the best way to minimize locks on the database side.

In test 2, you can try adding extra get () to txn2 before txn1.commit (). Then the second get () (where you are currently getting txn2 get) should return null.

+4
source

Source: https://habr.com/ru/post/1400524/


All Articles