2011-05-30 86 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所以如果任何人明白它應該如何處理,請更新。