Непоследовательное поведение транзакций в Appengine Local Datastore? - PullRequest
4 голосов
/ 09 марта 2012

Документы Appengine говорят об операциях в хранилище данных: 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.

Имея это в виду, я создал следующие два модульных теста для проверки этого (в сравнении с локальным хранилищем данных). Я ожидаю, что оба моих теста ниже пройдут. Тем не менее, только «test1» проходит, а «test2» не удается. Единственная разница - это фиксация tx1 в "test1".

Это ошибка в локальном хранилище данных, неправильное понимание документации 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();
        }
    }
}

1 Ответ

4 голосов
/ 09 марта 2012

Я подозреваю, что транзакция фактически не начинается, когда вы вызываете datastore.beginTransaction - она ​​начинается, когда транзакция впервые попадает в базу данных - это было бы оптимальным способом минимизировать блокировки на стороне базы данных.

В тесте 2 вы можете попробовать добавить дополнительный метод get () в txn2 перед txn1.commit (). Затем второй get () (где вы в настоящий момент делаете get txn2) должен вернуть null.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...