2011-08-26 87 views
8

根據Java Persistent/Locking wikibooks *,處理鎖定的最佳方法是向用戶報告樂觀鎖定錯誤/例外。如何處理鎖定(JPA)?

問題是它不可擴展。假設我有很多用戶可能會使用相同的動作導致鎖定。用戶不關心鎖定錯誤消息。

一言以蔽之:

  • 最好的辦法是禁用所有的鎖?
  • 最好的方法是向用戶報告錯誤鎖定消息?但用戶必須重試他的行動,直到它可以工作!
  • 最好的方法是重試交易,直到沒有鎖?

*

處理樂觀鎖異常

不幸的是程序員經常可以對自己好太聰明瞭。使用樂觀鎖定時出現的第一個問題是發生OptimisticLockException時應該怎麼做。友好的鄰居超級程序員的典型反應是自動處理異常。他們只會創建一個新的事務,刷新對象以重置其版本,並將數據合併回對象並重新提交。 Presto問題解決了,還是它?

這實際上首先破壞了整個鎖定點。如果這是你的願望,那麼你最好不要使用鎖定。不幸的是,OptimisticLockException應該很少被自動處理,並且你真的需要打擾用戶這個問題。您應該向用戶報告衝突,並且或者說「發生了抱歉,但發生了編輯衝突,並且他們將不得不重做他們的工作」,或者在最好的情況下,刷新對象並向用戶提供當前數據以及他們提交的數據並幫助他們將兩者合併在一起。

一些自動合併工具會比較數據的兩個衝突版本,如果沒有一個單獨的字段發生衝突,那麼數據將自動合併,而無需用戶的幫助。這是大多數軟件版本控制系統所做的。不幸的是,用戶通常能夠更好地判斷何時發生衝突而不是程序,這是因爲兩個版本的.java文件沒有改變同一行代碼並不意味着沒有衝突,第一個用戶可能已經刪除了另一個用戶添加了一個方法來引用的方法,以及其他一些可能導致典型的夜間構建經常被破壞的問題。

+0

的可能重複[如何禁用JPA的鎖系統?(http://stackoverflow.com/questions/7201940/how-to-disable-the-lock-system-of-jpa),從同作者。 –

+2

我會說他們沒有重複,因爲有人問如何禁用,另一個人要求鎖定策略。 – edutesoy

回答

10

用戶會關心該消息,因爲他想做一些修改,並且尚未進行修改。他將因此刷新頁面以查看數據的新狀態,並將重做其修改,或者決定在新狀態下不應再製作它們。

這是一個問題,如果兩個用戶同時修改一個實體,並且如果最後一次修改獲勝,無論修改是什麼?如果是問題,請使用樂觀鎖定,並在出現問題時通知用戶。沒有辦法繞過它。

如果不是問題,那就不要使用樂觀鎖定。最後的修改,如果它沒有破壞數據庫中的約束,將永遠贏。但有併發用戶修改相同的數據將總是導致異常(例如,因爲有些用戶可能會有些其他用戶提交一個修改到同一實體之前刪除實體)。

重試是不是一種選擇:

  • 要麼它會再次失敗,因爲它只是無法做修改
  • 或它會成功,但將擊敗其在樂觀鎖點第一名。

你的問題可以用汽車來比喻來解釋。假設您選擇購買帶限速器的汽車,以確保您不會違反限速。現在你問:但我不在乎速度限制。我不應該永遠禁用限速器嗎?你可以,但是如果你被警方抓住,不要感到驚訝。

+0

感謝您的優秀解釋 –