天天看點

鎖的分類(一)

  • 簡介
  • 鎖的分類(一)
  • ​從資料操作的類型劃分​

    ​:讀鎖、寫鎖
讀鎖 :也稱為 共享鎖 、英文用 S 表示。針對同一份資料,多個事務的讀操作可以同時進行而不會互相影響,互相不阻塞的。
寫鎖 :也稱為 排他鎖 、英文用 X 表示。目前寫操作沒有完成前,它會阻斷其他寫鎖和讀鎖。這樣就能確定在給定的時間裡,隻有一個事務能執行寫入,
并防止其他使用者讀取正在寫入的同一資源。
對于 InnoDB 引擎,讀鎖和寫鎖既可以加在表上,也可以加在行上

2個讀鎖是相容的
1個讀鎖1個寫鎖是不相容的
2個寫鎖是不相容的      
  • 鎖定讀
# 讀的時候加S鎖
SELECT ... LOCK IN SHARE MODE;
# 寫法2
SELECT ... FOR SHARE;

# 讀的時候加X鎖
SELECT ... FOR UPDATE;      
  • 代碼案例
# 案例1:開啟2個共享鎖
# 打開1個mysql頁面
# 開啟1個事務
begin
# 讀user表的時候加S鎖
select * from user for share;
# 目前事務未關閉時,打開第2個mysql頁面
# 開啟第2個事務
begin
# 讀user表的時候加S鎖
select * from user for share;
# 可以讀取到資料

# 案例2:開啟1個共享鎖,開啟1個排他鎖
# 打開1個mysql頁面
# 開啟1個事務
begin
# 讀user表的時候加X鎖
select * from user for update;
# 目前事務未關閉時,打開第2個mysql頁面
# 開啟第2個事務
begin
# 讀user表的時候加X鎖
select * from user for update;
# 這時第2個mysql頁面中會阻塞,因為共享鎖和排他鎖是不相容的
# 需要關閉第1個事務
commit
# 這時第2個mysql頁面中才查詢到資料      
  • NOWAIT、SKIP LOCKED文法
# 在SELECT ...FOR UPDATE或SELECT ...FOR SHARE後面添加NOWAIT、SKIP LOCKED文法
# NOWAIT會立即報錯傳回
# SKIP LOCKED也會立即傳回,隻是傳回的結果中不包含被鎖定的行      
  • 代碼案例
# 案例1:使用NOWAIT
# 打開1個mysql頁面
# 開啟1個事務
begin
# 讀user表的時候加X鎖
select * from user for update;
# 目前事務未關閉時,打開第2個mysql頁面
# 開啟第2個事務
begin
# 讀user表的時候加X鎖
select * from user for update nowait;
# 這時第2個mysql頁面中,因為共享鎖和排他鎖是不相容的,會直接傳回報錯資訊

# 案例1:使用SKIP LOCKED
# 打開1個mysql頁面
# 開啟1個事務
begin
# 讀user表的時候加X鎖
select * from user for update;
# 目前事務未關閉時,打開第2個mysql頁面
# 開啟第2個事務
begin
# 讀user表的時候加X鎖
select * from user for update skip locked;
# 這時第2個mysql頁面中,因為共享鎖和排他鎖是不相容的,會直接傳回沒有鎖定的行      

繼續閱讀