MySQL 共享鎖 (lock in share mode),排他鎖 (for update)

hiword發表於2018-06-02

共享鎖(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,才可

原創地址:http://blog.crcms.cn

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章