Java持久性锁定初学者指南
隱式鎖定
在并發理論中,鎖定用于保護可變共享數據免受危險數據完整性異常的影響。 因為鎖管理是一個非常復雜的問題,所以大多數應用程序都依賴于其數據提供程序隱式鎖定技術。
將整個鎖定職責委托給數據庫系統既可以簡化應用程序開發,又可以防止諸如死鎖之類的并發問題。 死鎖仍然可能發生,但是數據庫可以檢測并采取安全措施(任意釋放兩個競爭鎖之一)。
物理鎖
大多數數據庫系統使用共享(讀取)和排他(寫入)鎖,這歸因于特定的鎖定元素(行,表)。 盡管SQL標準要求物理鎖定,但是悲觀的方法可能會阻礙可伸縮性。
現代數據庫已實現了輕量級鎖定技術,例如多版本并發控制 。
隱式數據庫鎖定隱藏在事務隔離級別配置的后面。 每個隔離級別都帶有預定義的鎖定方案,旨在防止某些數據完整性異常集。
READ COMMITTED對當前事務修改的數據使用查詢級共享鎖和排他鎖。 REPEATABLE READ和SERIALIZABLE在讀取時使用事務級共享鎖,在寫入時使用互斥鎖。
邏輯鎖
如果數據庫鎖定足以用于批處理系統,則多請求Web流將跨越多個數據庫事務。 對于長時間的對話 ,邏輯(樂觀)鎖定機制更為合適。
與對話級別的可重復讀取存儲結合使用 ,樂觀鎖定可以確保數據完整性,而無需犧牲可伸縮性。
JPA支持開放式鎖定和持久性上下文可重復讀取,使其非常適合實現邏輯事務。
顯式鎖定
盡管對于大多數應用程序并發控制要求,隱式鎖定可能是最佳選擇,但有時您可能需要更細粒度的鎖定策略。
大多數數據庫系統都支持查詢時排他鎖定指令,例如SELECT FOR UPDATE或SELECT FOR SHARE 。 因此,我們可以使用較低級別的默認隔離級別(READ COMMITTED),同時為特定事務方案請求共享或排他鎖。
大多數樂觀鎖定實現只驗證修改后的數據,但是JPA也允許顯式樂觀鎖定。
JPA鎖定
作為數據庫抽象層,JPA可以從基礎RDBMS提供的隱式鎖定機制中受益。 對于邏輯鎖定,JPA還提供了可選的自動實體版本控制機制。
JPA支持以下操作的顯式鎖定:
- 尋找一個實體
- 鎖定現有的持久性上下文實體
- 刷新實體
- 查詢通過JPQL,標準或本機查詢
顯式鎖類型
LockModeType包含以下樂觀和悲觀鎖定模式:
| 沒有 | 在沒有顯式鎖定的情況下,應用程序將使用隱式鎖定(樂觀或悲觀) |
| 樂觀的 | 始終在事務提交時發出版本檢查,因此確保樂觀鎖定可重復讀取。 |
| 讀 | 與OPTIMISTIC相同。 |
| OPTIMISTIC_FORCE_INCREMENT | 始終增加實體版本(即使實體不變),并在事務提交時發出版本檢查,從而確保樂觀鎖定可重復讀取。 |
| 寫 | 與OPTIMISTIC_FORCE_INCREMENT相同。 |
| PESSIMISTIC_READ | 獲取共享鎖以防止任何其他事務獲取PESSIMISTIC_WRITE鎖。 |
| PESSIMISTIC_WRITE | 獲取排他鎖以防止任何其他事務獲取PESSIMISTIC_READ或PESSIMISTIC_WRITE鎖。 |
| PESSIMISTIC_FORCE_INCREMENT | 獲取數據庫鎖以防止任何其他事務獲取PESSIMISTIC_READ或PESSIMISTIC_WRITE鎖,并且在提交事務時會增加實體版本。 |
鎖定范圍和超時
JPA 2.0定義了javax.persistence.lock.scope屬性,采用以下值之一:
- NORMAL由于對象圖可以跨越多個表,因此顯式的鎖定請求可能會傳播到多個表(例如,聯接繼承,輔助表)。由于整個實體關聯的行被鎖定,因此多對一和一對-一對一的外鍵也將被鎖定,但不會鎖定另一側的父級關聯。 此范圍不會傳播到子級集合。
- 擴展顯式鎖將傳播到元素集合和聯結表 ,但不會鎖定實際的子實體。 該鎖僅在防止幻像讀取或更改實際子實體狀態的同時,用于防止刪除現有子實體時有用。
JPA 2.0還引入了javax.persistence.lock.timeout屬性,使我們可以配置在拋出PessimisticLockException之前鎖定請求將等待的時間(毫秒)。
休眠鎖定
Hibernate支持所有JPA鎖定模式和一些其他特定的鎖定選項。 與JPA一樣,可以為以下操作配置顯式鎖定:
- 使用各種LockOptions設置鎖定實體。
- 得到一個實體
- 加載實體
- 刷新實體
- 創建實體或本機查詢
- 創建條件查詢
LockModeConverter負責映射JPA和Hibernate鎖定模式,如下所示:
| 沒有 | 沒有 |
| 樂觀的 讀 | 樂觀的 |
| OPTIMISTIC_FORCE_INCREMENT 寫 | OPTIMISTIC_FORCE_INCREMENT |
| PESSIMISTIC_READ | PESSIMISTIC_READ |
| PESSIMISTIC_WRITE 升級 UPGRADE_NOWAIT UPGRADE_SKIPLOCKED | PESSIMISTIC_WRITE |
| PESSIMISTIC_FORCE_INCREMENT 力 | PESSIMISTIC_FORCE_INCREMENT |
不建議使用UPGRADE和FORCE鎖定模式,而推薦使用PESSIMISTIC_WRITE 。
UPGRADE_NOWAIT和UPGRADE_SKIPLOCKED分別使用Oracle風格的select用于更新nowait或select用于更新跳過鎖定語法。
鎖定范圍和超時
Hibernate還定義了作用域和超時鎖定選項 :
- 范圍
鎖定范圍允許顯式鎖定級聯到所擁有的關聯 。 - 超時
超時間隔可能會阻止鎖定請求無限期地等待。
在我的下一篇文章中,我將介紹不同的顯式鎖定設計樣式,敬請期待!
翻譯自: https://www.javacodegeeks.com/2015/01/a-beginners-guide-to-java-persistence-locking.html
總結
以上是生活随笔為你收集整理的Java持久性锁定初学者指南的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux合并多个文件为一个(linux
- 下一篇: 重置安卓手机密码(重置安卓手机)