2012-07-06 128 views
1

鎖定我有低於類似的代碼,我試圖找出事務鎖:交易與AppEngine上

DAOT.repeatInTransaction(new Transactable() { 
     @Override 
     public void run(DAOT daot) 
     { 
       Points points = daot.ofy().find(Points.class, POINTS_ID); 
       // do something with points 
       takes_a_very_long_time_delay(); // perhaps 10 secs 
       daot.ofy().put(points); 
     } 
}); 

以上是從一個Java servlet中執行的代碼。例如,該操作預計可以工作10秒鐘。在那段時間之間,我有一個測試會調用另一個servlet,它會刪除一個Points實體,我期待刪除操作會失敗,或者至少在上述事務完成後刪除實體。

但是,在上述代碼執行期間,實體被刪除。在我的真實應用程序中,我嘗試訪問或編輯不存在的實體時添加了異常處理以引發異常。

從那裏,應用程序就在我執行,將在上面的代碼刪除實體在servlet拋出「Entity not found"例外。

雖然我使用GAE交易已經,但是我覺得我還是失去了一些東西這就是爲什麼我的測試失敗

代碼爲刪除事務從withing刪除的servlet:

DAOT.repeatInTransaction(new Transactable() { 
     @Override 
     public void run(DAOT daot) 
     { 
       Points points = daot.ofy().find(Points.class, POINTS_ID); 
       daot.ofy().delete(points); 
     } 
}); 

我怎樣才能確保像delete爲f的新的操作或者一個實體將在交易期間等到當前操作發生在一個實體上?

回答

5

App Engine使用樂觀併發性,而不是鎖定。也就是說,一組實體上的事務不會阻止其他進程在事務運行時修改這些實體。相反,當事務嘗試提交時,它將檢查在事務執行時是否進行了修改,如果有,則從一開始就放棄所有更改並再次運行您的函數。

+0

在提交期間丟棄哪個事務?一個是執行第一個還是第二個執行? – xybrek 2012-07-10 06:52:36

+4

@xybrek第二個被執行的人 - 因爲觀察底層數據的人在工作時被修改過。 – 2012-07-10 09:05:53

1

我假設你使用objectify來處理數據存儲。 首先,您需要確保daot.ofy()返回具有顯式事務集(ObjectifyFactory.beginTransaction())的Objectify實例,而不是ObjectifyFactory.begin()。然後確保對find()和delete()調用(以及find()/ put對)使用相同的對象化實例。