4

하는 App Engine 문서는 데이터 저장소의 거래에 대해 이런 말 : 그와 http://code.google.com/appengine/docs/java/datastore/transactions.html#Isolation_and_ConsistencyAppengine Local Datastore에서 일관성없는 트랜잭션 동작이 발생합니까?

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. 

염두에두고, 내가 만든 다음 두 가지 단위 테스트 (로컬 데이터 저장소에 대해)이 테스트 할 수 있습니다. 아래 두 가지 테스트가 모두 통과 될 것으로 기대합니다. 그러나 "test1"만 통과하는 반면 "test2"는 실패합니다. 유일한 차이점은 "test1"에서 tx1 커밋입니다.

로컬 데이터 저장소의 버그, GAE 문서의 오해 또는 유닛 테스트의 버그입니까? 또는 다른 것?

감사합니다.

@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(); 
     } 
    } 
} 
+0

'test1'에'commit()'이 없습니까? –

답변

4

난 당신이 datastore.beginTransaction를 호출 할 때 때 트랜잭션이 실제로 시작하지 않는 생각 - 트랜잭션이 먼저 데이터베이스를 칠 때 그것은 시작 - 데이터베이스 측에서 잠금을 최소화 할 수있는 최적의 방법이 될 것이라고.

테스트 2에서는 txn1.commit() 전에 txn2에 추가 get()을 넣을 수 있습니다. 그런 다음 두 번째 get() (현재 txn2 get을 수행하는 곳)은 null을 반환해야합니다.

+0

예, 당신의 의혹이 맞았습니다. 첫 번째 트랜잭션을 커밋하기 전에 두 번째 트랜잭션에서 get()을 수행하면 데이터 저장소에서 실제 트랜잭션이 시작되는 것으로 보입니다. 이 동작이 실제 Datastore에서는 동일하지만 100 % 확신 할 수는 없습니다. 당신의 도움을 주셔서 감사합니다! – sappenin