JPA实体锁定模式的差异
JPA本質上提供了兩種鎖定機制,以幫助同步對實體的訪問。 兩種機制都可以防止以下情況:兩個事務在不知道的情況下相互覆蓋數據。
通過實體鎖定,我們通常希望通過2個并行事務來防止以下情況:
結果,亞當所做的更改完全被芭芭拉(Barbara)所取代,甚至沒有引起她的注意。 像這樣的場景有時被稱為臟讀 。 顯然,理想的結果是Adam編寫XA,而Barbara被迫在編寫XB之前檢查XA更改。
樂觀鎖的工作原理
樂觀鎖定基于這樣的假設:沖突非常少見;如果發生沖突,則拋出錯誤是可以接受的,并且比防止沖突更方便。 允許其中一項交易正確完成,但其他任何交易都會例外回滾,并且必須重新執行或丟棄。
通過樂觀鎖定,亞當和芭芭拉可能出現以下情況:
如您所見,芭芭拉被迫審查亞當的更改,如果她決定,她可能會修改亞當的更改并保存(合并更改)。 最終數據包含亞當和巴巴拉的變化。
JPA完全控制樂觀鎖定。 它需要數據庫表中的其他版本列。 它完全獨立于用于存儲關系數據的基礎數據庫引擎。
悲觀鎖定如何工作
對于某些人來說,悲觀鎖定被認為是很自然的。 當事務需要修改實體(可以由另一個事務并行修改)時,事務將發出鎖定該實體的命令。 所有鎖將保留到事務結束,然后自動釋放。
使用悲觀鎖,情況可能是這樣的:
如我們所見,Barbara再次被迫編寫XAB,其中也包含Adam所做的更改。 但是,該解決方案與樂觀方案完全不同–芭芭拉需要等待亞當的交易完成后才能讀取數據。 此外,我們需要在兩個事務中手動發出鎖定命令,以使該方案起作用。 (由于我們不確定亞當或芭芭拉首先要處理哪個事務,因此兩個事務都需要在修改數據之前先鎖定數據。)樂觀鎖定比悲觀鎖定需要更多的設置,每個實體都需要使用version列,但隨后我們不需要記住在交易中發出鎖。 JPA自動執行所有檢查,我們只需要處理可能的異常。
悲觀鎖定使用基礎數據庫提供的鎖定機制鎖定表中的現有記錄。 JPA需要知道如何觸發這些鎖定,并且某些數據庫不完全支持。
甚至JPA規范都說,不需要提供PESSIMISTIC_READ(因為許多數據庫僅支持WRITE鎖):
這是允許的,以使用實施LockModeType.PESSIMISTIC_WRITE其中LockModeType.PESSIMISTIC_READ請求,而不是相反。
JPA中可用鎖類型的列表
首先,我想說的是,如果實體中提供了@Version列,則JPA會默認為此類實體打開樂觀鎖定。 您不需要發出任何鎖定命令。 但是,您可以隨時使用以下一種鎖類型發出鎖:
- 這確實是默認設置。 如ObjectDB所述,通常將其忽略。 在我看來,它只是存在的,這樣您就可以動態地計算鎖定模式,即使鎖定最終是最優的,也可以進一步傳遞它。 雖然用例不是很可能,但是提供一個甚至引用默認值的選項也是一種很好的API設計。
- 示例:Java LockModeType lockMode = resolveLockMode(); A a = em.find(A.class, 1, lockMode);
- 這是很少使用的選項。 但是,如果您想鎖定另一個實體對這個實體的引用,這可能是合理的。 換句話說,即使您未修改某個實體,您也希望鎖定該實體的工作,但是其他實體也可能相對于該實體而被修改。
- 例:
- 我們有實體書和書架。 可以將Book添加到書架中,但是book沒有對其書架的引用。 鎖定將書移動到書架上的操作是合理的,這樣一本書不會最終出現在兩個書架中。 要鎖定此操作,僅鎖定當前書架實體是不夠的,因為書還不必在書架上。 鎖定所有目標書架也沒有意義,因為它們在不同交易中可能會有所不同。 唯一有意義的是鎖定書本實體本身,即使在我們這種情況下它沒有被更改(它不保留對其書架的引用)。
- 此模式類似于LockModeType.PESSIMISTIC_WRITE ,但有一點不同:在通過某種事務在同一實體上施加寫鎖定之前,它不應阻止讀取實體。 它還允許其他事務使用LockModeType.PESSIMISTIC_READ鎖定。 WRITE和READ鎖之間的區別在這里(ObjectDB)和這里(OpenJPA)都有很好的解釋。 但是,由于規范允許,很多情況下,它的行為類似于LockModeType.PESSIMISTIC_WRITE ,許多提供程序并未單獨實現它。
- 這是LockModeType.PESSIMISTIC_READ的增強版本。 有了WRITE鎖定后,JPA借助數據庫將阻止任何其他事務讀取該實體,而不僅僅是像READ鎖定那樣進行寫入。
- 這是另一種很少使用的鎖定模式。 但是,這是您需要結合PESSIMISTIC和OPTIMISTIC機制的一種選擇。 在以下情況下,使用普通的PESSIMISTIC_WRITE可能會失敗:
- 事務A使用樂觀鎖定并讀取實體E
- 事務B獲得對實體E的WRITE鎖定
- 事務B提交并釋放E的鎖
- 事務A更新E并提交
為了發出某種類型的鎖,JPA提供了以下方法:
- 一些EntityManager方法接受一個可選參數來指定鎖定類型,例如:
- find(類entityClass,Object primaryKey,LockModeType lockMode)
- 查詢還提供setLockMode(LockModeType lockMode)方法來鎖定將由查詢檢索的所有實體
您可以在JPA中使用兩種類型的鎖定機制中的任何一種。 如果您使用類型PESSIMISTIC_FORCE_INCREMENT悲觀鎖,也可以在必要時將它們混合使用。
- 要了解更多信息,請閱讀Vlad Mihalcea的優秀博客。
翻譯自: https://www.javacodegeeks.com/2016/02/differences-jpa-entity-locking-modes.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的JPA实体锁定模式的差异的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信注销账号
- 下一篇: java 堆大小_适当的Java堆大小的