共享鎖 (lock in share mode)
簡介
允許不同事務之前共享加鎖讀取,但不允許其它事務修改或者加入排他鎖
如果有修改必須等待一個事務提交完成,纔可以執行,容易出現死鎖
共享鎖事務之間的讀取
session1:
start transaction;
select * from test where id = 1 lock in share mode;
session2:
start transaction;
select * from test where id = 1 lock in share mode;
此時 session1 和 session2 都可以正常獲取結果,那麼再加入 session3 排他鎖讀取嘗試
session3:
start transaction;
select * from test where id = 1 for update;
在 session3 中則無法獲取數據,直到超時或其它事物 commit
Lock wait timeout exceeded; try restarting transaction
共享鎖之間的更新
當 session1 執行了修改語句:
session1:
update test set name = 'kkkk' where id = 1;
可以很多獲取執行結果。
當 session2 再次執行修改 id=1 的語句時:
session2:
update test set name = 'zzz' where id = 1;
就會出現死鎖或者鎖超時,錯誤如下:
Deadlock found when trying to get lock; try restarting transaction
或者:
Lock wait timeout exceeded; try restarting transaction
必須等到 session1 完成 commit 動作後,session2 纔會正常執行,如果此時多個 session 併發執行,可想而知出現死鎖的機率將會大增。
session3 則更不可能
結論:
mysql 共享鎖 (lock in share mode
)
- 允許其它事務也增加共享鎖讀取
- 不允許其它事物增加排他鎖 (
for update
) - 當事務同時增加共享鎖時候,事務的更新必須等待先執行的事務 commit 後才行,如果同時併發太大可能很容易造成死鎖
共享鎖,事務都加,都能讀。修改是惟一的,必須等待前一個事務 commit,纔可
排他鎖 (for update)
簡介
當一個事物加入排他鎖後,不允許其他事務加共享鎖或者排它鎖讀取,更加不允許其他事務修改加鎖的行。
排他鎖不同事務之間的讀取
同樣以不同的 session 來舉例
session1:
start transaction;
select * from test where id = 1 for update;
session2:
start transaction;
select * from test where id = 1 for update;
當 session1 執行完成後,再次執行 session2,此時 session2 也會卡住,無法立刻獲取查詢的數據。直到出現超時
Lock wait timeout exceeded; try restarting transaction
或 session1 commit 纔會執行
那麼再使用 session3 加入共享鎖嘗試
select * from test where id = 1 lock in share mode;
結果也是如此,和 session2 一樣,超時或等待 session1 commit
Lock wait timeout exceeded; try restarting transaction
排他鎖事務之間的修改
當在 session1 中執行 update 語句:
update test set name = 123 where id = 1;
可以正常獲取結果
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
此時在 session2 中執行修改
update test set name = 's2' where id = 1;
則會卡住直接超時或 session1 commit, 纔會正常吐出結果
session3 也很明顯和 session2 一樣的結果,這裏就不多贅述
總結
- 事務之間不允許其它排他鎖或共享鎖讀取,修改更不可能
- 一次只能有一個排他鎖執行 commit 之後,其它事務纔可執行
不允許其它事務增加共享或排他鎖讀取。修改是惟一的,必須等待前一個事務 commit,纔可