事務一致性的測試

框架:spring

數據庫:innodb

代碼地址

spring事務的串行化

isolation=Isolation.SERIALIZABLE

  • 多個串行化事務發生衝突會拋出死鎖異常

  • 串行化和不可重複讀發生衝突的情況

事務1:串行化

事務2:不可重複讀(默認隔離級別)

執行順序 結果
1開啓 - 2開啓 - 2結束 - 1結束 事務1正常,事務2發生死鎖異常
1開啓 - 2開啓 - 1結束 - 2結束 事務2的操作覆蓋了事務1的操作
2開啓 - 1開啓 - 1結束 - 2結束 事務2的操作覆蓋了事務1的操作
2開啓 - 1開啓 - 2結束 - 1結束 事務1正常,事務2發生死鎖異常

總結:

  1. 事務1開啓時給數據上鎖,具體哪種鎖沒有研究
  2. 如果事務2先結束,提交事務時由於事務1沒有釋放鎖,所以會發生死鎖異常,這種結果可以保證一致性
  3. 如果事務2後結束,提交事務時事務1已經釋放了鎖,事務2使用舊數據更新數據庫導致數據不一致

排他鎖(悲觀鎖)

前提:需要保證一致的邏輯在一個事務中

先申請排他鎖

加鎖:select … for update

例如:

SELECT id, value
FROM t_pessimistic
WHERE id = 1
FOR UPDATE

會對查詢結果的每行加排他鎖

如果沒有其他事務對查詢結果中的任一行使用排他鎖時可以成功獲得鎖,否則會阻塞直到獲得鎖

如果發生衝突的機率較低,每次都加鎖會產生額外開銷

適合發生衝突機率高的情況

樂觀鎖

代碼中實現的樂觀鎖好像不太穩定

給需要保證一致性的表增加版本號字段

每次執行update或delete時,驗證版本號,如果不一致就重試

如果發生衝突的機率較高,可能會重試多次,反而影響效率

適合發生衝突機率低的情況

總結

要保證數據的一致性,同一個表應該使用同一種鎖

歡迎補充

發佈了29 篇原創文章 · 獲贊 19 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章