mysql樂觀鎖實現

2021-10-04 20:44:08 字數 2319 閱讀 8731

各鎖的概念

悲觀鎖:假定會發生併發衝突,遮蔽一切可能違反資料完整性的操作

悲觀鎖,從字面理解就是很悲觀,每次去拿資料的時候都認為別人會修改,所以在每次拿的時候對資料上鎖,這樣就保證了資料的準確性。比如mysql中的表鎖,行鎖。

表鎖:當你對一張表進行修改時,會鎖死整張表,其他的請求需要在修改完成釋放鎖才能繼續。在高併發的情景下不適用。

行鎖:當你對一張表的某一行資料修改時,會鎖死這一行資料,對錶中其他的資料沒影響。行鎖在保證資料準確性的同時也保證了效率,但一定程度上增加了系統的開銷。

樂觀鎖: 假設不會發生併發衝突,只在提交操作時檢查是否違反資料完整性。

樂觀鎖,在每次去拿資料的時候認為別人不會修改,不對資料上鎖,但是在提交更新的時候會判斷在此期間資料是否被更改,如果被更改則提交失敗。

樂觀鎖的實現:

使用版本控制字段,再利用行鎖的特性實現樂觀鎖,如下

有一張訂單表order,有欄位id、order_no、 price,  為實現樂觀鎖控制,新增version欄位,預設值為0

order

id    1

order_no    123456

price    5

version    0

假設兩個人同時進來修改該條資料,操作為:

1. 先查詢該資料   select * from order where id = 1

2. 修改該條資料  update order set price = 1 where id = 1

如果兩個人同時查詢到該條資料price = 5, 可以執行update操作, 但任意一方還沒執行update操作,那麼最後雙方都執行update,導致資料被修改兩次,產生髒資料 !

使用version欄位控制版本後:

1. 兩人先查詢該資料 select * from order where id = 1

此時兩人查詢到的資料一樣,id = 1, price = 5, order_no = 123456, version = 0

2. 兩人都發現該條資料price = 5, 符合update條件,第一人執行update(因為mysql行鎖的特性,兩人不可能同時修改一條資料,所以update同一條資料的時候,是有先後順序的,只有在第乙個執行完update,才能釋放行鎖,第二個繼續進行update): 

update order set price = 1, version = version + 1 where id = 1 and version = 0

執行完成後,version字段值將變成1, 第二人執行update:

update order set price = 1, version = version + 1 where id = 1 and version = 0

此時的version的值已經被修改為1,所以第二人修改失敗,實現樂觀鎖控制。

死鎖的處理:

資料庫使用樂觀鎖導致產生死鎖:

事務aupdate order set price = 1 where id = 1

update order set price = 2 where id = 2

事務bupdate order set price = 1 where id = 2

update order set price = 2 where id = 1

假設在兩個事務中有以上兩個操作,同時修改order表中兩條資料

事務a在執行完第一條update的時候,剛好事務b也執行完第一條update

此時, 事務a中order表中的id = 1的行被鎖住, 事務b中order表中id = 2的行被鎖住,兩個事務繼續往下執行

事務a中第二條update執行需要order表中id = 2的行資料,而事務b中第二條update執行需要id = 1的行資料, 兩條update往下執行的條件都需要對方事務中已經被鎖住的行,於是陷入無限等待,形成死鎖。

解決死鎖的產生:

指定鎖的執行順序,比如把以上兩事務稍作修改

事務aupdate order set price = 2 where id = 2

update order set price = 1 where id = 1

事務bupdate order set price = 1 where id = 2

update order set price = 2 where id = 1

事務a執行第一條update時,id = 2 的行被鎖住,此時,事務b想修改id = 2的行,只能等待事務a執行完成,當事務a執行完成時,事務b再執行, 這樣就不會產生死鎖了。

mysql樂觀鎖實現 mysql樂觀鎖實現

在多使用者環境中,在同一時間可能會有多個使用者更新相同的記錄,這會產生衝突。這就是著名的併發性問題。典型的衝突有 1.丟失更新 乙個事務的更新覆蓋了其它事務的更新結果,就是所謂的更新丟失。例如 使用者a把值從6改為2,使用者b把值從2改為6,則使用者a丟失了他的更新。2.髒讀 當乙個事務讀取其它完成...

mysql 樂觀鎖實現 mysql 樂觀鎖實現

一 為什麼需要鎖 併發控制 在多使用者環境中,在同一時間可能會有多個使用者更新相同的記錄,這會產生衝突。這就是著名的併發性問題。典型的衝突有 1.丟失更新 乙個事務的更新覆蓋了其它事務的更新結果,就是所謂的更新丟失。例如 使用者a把值從6改為2,使用者b把值從2改為6,則使用者a丟失了他的更新。2....

mysql 樂觀鎖實現

一 為什麼需要鎖 併發控制 在多使用者環境中,在同一時間可能會有多個使用者更新相同的記錄,這會產生衝突。這就是著名的併發性問題。典型的衝突有 1.丟失更新 乙個事務的更新覆蓋了其它事務的更新結果,就是所謂的更新丟失。例如 使用者a把值從6改為2,使用者b把值從2改為6,則使用者a丟失了他的更新。2....