2011-05-30 84 views
3

我不知道我是否了解谷歌文档,我想知道如果别人可以检查我的理解。正确处理使用谷歌应用程序引擎的交易回滚

是保证永远只能下面的代码做以下两项:

  • 更新到银行账户余额
  • 店的交易记录。

下面是我的理解是正确的:

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

这是正确的。然而,没有必要在该实体中包含帐户的密钥 - 您创建的实体是该帐户的子帐户。

+0

使用retries计数器处理重新尝试交易的操作是直接从Google文档复制的(http://code.google.com/appengine/docs/java/datastore/transactions.html#Uses_​​for_Transactions)。 – Jacob 2011-05-30 08:36:24

+0

@Jacob我的错误。 Python SDK自动重试;正如文档所说,Java的显然没有。 – 2011-05-30 10:05:27

0

不一定是ConcurrentModificationException表示事务失败。在文档http://code.google.com/appengine/docs/java/datastore/transactions.html中提到“如果您的应用在提交事务时收到异常,并不总是意味着事务失败,那么在提交事务的情况下,您可能会收到DatastoreTimeoutException,ConcurrentModificationException或DatastoreFailureException异常并最终成功应用,只要有可能,使您的数据存储交易幂等,以便如果您重复交易,最终结果将是相同的。“ 我在这里为这个问题创建了一个单独的主题Transactions and ConcurrentModificationException documentation ambiguity所以如果任何人明白它应该如何处理,请更新。