jpa mysql乐观锁_JPA @Lock(value = LockModeType.PESSIMISTIC_WRITE) 悲观锁防坑
前提:
由于業務需要在entity Product已經實現了@version的樂觀鎖的基礎上再加上了悲觀鎖的控制
@Lock(value = LockModeType.PESSIMISTIC_WRITE)
Product findByType(String type);
詳情描述:
但是當進行多請求的并發測試的時候發現程序第一個搶占findByType的請求能正常上鎖,其它并發請求也正常進入等待,可是當第一個請求修改product并且提交事務釋放鎖的時候,其它等待請求準備上鎖的時候卻拋出了樂觀鎖的錯誤,為什么會出現這種錯誤呢?
解答:
JPA 提供的@Lock 不是直接對findByType生成的對應查詢語句后面加for update上鎖,而是按照下面的順序來上鎖的:
執行查詢語句: select * from product where type = ?
查詢結果(id, type, version): [1001, 'NEW', 1]
通過查詢出來的id, version在執行以下查詢
select * from product where product id = 1001 and version = 1
如果步驟2查詢有數據返回的話就生成下面的for update的查詢SQL上鎖, 如果沒有就拋出樂觀鎖異常。
select * from product where product id = 1001 and version = 1 for update
根據@Lock的上述執行原理,當觸發多請求并發的時候,所有請求都同步執行了上述1的查詢操作,當執行步驟2,3的時候先上鎖的請求修改了數據和版本后,后續請求在舊的version就查詢不出來數據就拋出了樂觀鎖異常了。
建議:
一般情況下盡量避免使用悲觀鎖,對系統開銷很大,如果不得已需要用到的話還是直接寫for update的SQL直接上鎖。
總結
以上是生活随笔為你收集整理的jpa mysql乐观锁_JPA @Lock(value = LockModeType.PESSIMISTIC_WRITE) 悲观锁防坑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 西德黄鼠狼VTS1无炮塔坦克歼击车
- 下一篇: SU-152“塔兰”坦克歼击车