2017-02-16 78 views
0

讓我們假設我們有一個應用程序「郵件客戶端」和一個前端。用hibernate的樂觀/悲觀鎖定併發的好策略/解決方案

如果用戶正在輸入消息或編輯主題或其他內容,則會進行一次休息調用以更新用戶正在更改的任何內容(例如接收者)以將消息保留在DRAFT中。所以很多PUT正在發生以保存消息。關閉窗口時,每個可編輯字段的更新同時發生。 Hibernate無法處理這種併發性:這些調用中的每一個都檢索消息,編輯它們自己的字段並嘗試再次保存消息,而另一個調用已經改變它。

我知道我可以添加一個休息電話來同時保存所有的字段,但我想知道是否有一個更清潔的解決方案,或者一個體面的策略來處理這種情況(例如只更新一個字段或一些合併策略如果對象已經改變)

在此先感謝!

+0

https://www.google.com/search?q=hibernate+update+single+column&ie=utf-8&oe=utf-8#q=hibernate+update+single+field – ZhongYu

回答

0

最簡單的解決方案,這裏將是調整的UI要麼

  • 提交電子郵件提交,做必要的所有任務中一個REST調用。
  • 序列化其餘的調用,以便它們被鏈接而不是同時觸發。

的關注,我這裏的是,這會在某個時刻雪球多的用戶與應用程序交互成爲一個更大的併發問題。考慮一下當您面對100,500,1000或甚至10000或以上的併發用戶時,您的Web基礎架構必須單獨支持的併發休息呼叫的潛在數量。

當負載本身首先是設計缺陷的產物時,是否真的有意義增強服務器的容量來處理負載?

Hibernate旨在通過兩種機制處理鎖定,樂觀和悲觀。

樂觀的方式

  1. 閱讀從數據存儲實體。
  2. 緩存您要在臨時變量中修改的字段的副本。
  3. 根據您的PUT操作修改該字段或字段。
  4. 嘗試合併更改。
  5. 如果保存成功,就完成了。
  6. 如果出現OptimisticLockException,請從數據存儲刷新實體狀態。
  7. 將緩存的值與必須更改的字段進行比較。
  8. 如果值不同,則可以斷言或者拋出一個異常
  9. 如果他們沒有什麼不同,回去4.

樂觀方式的美麗的部分是你避免任何形式的發生死鎖,特別是如果你允許單獨讀取和鎖定多個表。

雖然您可以使用悲觀鎖定選項,但樂觀鎖定通常是處理併發操作的最佳接受方式,因爲它具有最少的併發爭用和性能影響。

+0

現在,我鏈接了電話(快速修復)。但是正如你所指出的那樣,一旦應用程序擴展,這是非常有問題的。我希望每次字段更改時都不要與所有字段進行一次通話。我正在考慮在hibernate中使用單個更新語句...這樣,不需要檢索對象 - >爲這些調用解決併發問題...雖然我想知道對完整應用程序會產生什麼樣的影響,因爲它不僅僅是一個簡單的郵件客戶端,而且是一個完全成熟的商業解決方案,用於加密消息傳遞,它使用obj的 –

+0

進行了大量預定的後處理。我更新了我的答案以包含使用樂觀鎖定的想法。您當然可以激發純粹的UPDATE語句,但是這並不能解決某些其他進程修改用戶嘗試修改的字段會發生什麼的問題。你的純粹的'UPDATE'方法接受了最後一個勝利的概念,而不是強迫非優先審查他們的變化,如果發生衝突。 – Naros