Корректная обработка отката транзакции с помощью Google App Engine - PullRequest
3 голосов
/ 30 мая 2011

Я не уверен, что я понимаю документацию Google, мне интересно, может ли кто-нибудь еще проверить мое понимание.

Гарантируется ли следующий код только когда-либо выполнять оба из следующих действий:

  • обновление баланса банковского счета
  • хранение записи о транзакции.

Ниже приведено то, что я понимаю правильно:

public void add(String account, Double value, String description, Date date) throws EntityNotFoundException {
    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    int retries = 3;
    while (true) {
        Transaction txn = datastore.beginTransaction();
        try {

            // Update the bank balance
            Key key = KeyFactory.createKey("Account", account);
            Entity e = datastore.get(key);
            Double balance = (Double) e.getProperty("balance");
            balance += value;
            e.setProperty("balance", value);
            datastore.put(e);

            // Record transaction details
            Entity d = new Entity("Transaction", key);
            d.setProperty("account_key", key);
            d.setProperty("date", date);
            d.setProperty("value", value);
            d.setProperty("description", description);

            txn.commit();
            break;
        } catch (ConcurrentModificationException e) {
            if (retries == 0) throw e;
            retries--;
        } finally {
            if (txn.isActive()) txn.rollback();
        }
    }
    }
}

Ответы [ 2 ]

2 голосов
/ 30 мая 2011

Это верно. Однако нет необходимости включать ключ учетной записи в сущность - создаваемая вами сущность является дочерней по отношению к рассматриваемой учетной записи.

0 голосов
/ 12 марта 2012

Не обязательно, что ConcurrentModificationException указывает на сбой транзакции.Это абсолютная неоднозначность в документации http://code.google.com/appengine/docs/java/datastore/transactions.html, где говорится «Если ваше приложение получает исключение при отправке транзакции, это не всегда означает, что транзакция не удалась. Вы можете получить исключения DatastoreTimeoutException, ConcurrentModificationException или DatastoreFailureException в случаяхгде транзакции были зафиксированы и в конечном итоге будут успешно применены. По возможности, сделайте ваши транзакции хранилища данных идемпотентными, чтобы в случае повторения транзакции конечный результат был бы таким же ».Я создал отдельную тему для этой проблемы здесь Транзакции и неоднозначность документации ConcurrentModificationException , поэтому, если кто-то понимает, как на самом деле это нужно делать, обновите также там.

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