[英]In java spring hibernate 3.6.3 how to tell a method to wait until lock is aqured and how to retry a failed transaction?
[英]How to retry a lock wait timeout using java persistence?
我需要對使用Java持久性時重試“可重試”異常(例如類似鎖等待超時之類)的正確方法進行一些說明。 例如,使用偽代碼,例如:
EntityTransaction tx = em.getTransaction();
tx.begin();
for (a bunch of objects) {
em.persist(object);
}
tx.commit();
如果數據庫中有鎖,有時會在em.persist調用中引發異常。 我可以將其包裝在try / catch中然后重試嗎(很明顯,有一些計數)? 還是我必須包裝整個tx.begin / commit並重做 ?
謝謝
假設沒有鎖定超時作為解決數據庫死鎖的方法,那么一個更簡單的解決方案是對請求使用更長的超時。 將超時設置為N * (C + 1)
秒,而不是使用N
秒的超時並重試最多C
次。
(如果您將鎖定超時用作死鎖的一種解決方法,那么您會遇到更大的問題。您最好嘗試解決死鎖的根本原因,因為即使使用C
重試,您的交易也有可能獲勝不能通過。)
只要EntityManager拋出的異常不會將事務標記為僅回滾(LockTimeoutException是此類示例之一,而PessimisticLockException並非如此),則可以繼續處理當前事務中的事務。
如果TX僅被標記為回滾,則您必須對TX進行保釋,然后重試TX內發生錯誤之前的任何嘗試,然后繼續操作。
如果要通過JPA循環進行工作,那么您很有可能是DELETE或UPDATE jpql查詢的候選人。
如果您按照規范進行編程,則實際上應該處置整個EntityManager並重新開始。 沒有任何例外可以保證在EM級別“可重試”。 如果persist()方法產生異常,則整個持久性會話將被視為不一致/不確定。
有時它將起作用。 我知道在休眠狀態下,您通常可以在樂觀鎖定異常之后嘗試獲得收益。 但是總的來說,如果您試圖捕獲並從entitymanager異常中恢復並保持相同的entitymanager,則您將依賴於供應商特定的行為,這些行為可能定義不清。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.