在讀取行上設置共享鎖。允許其他 Session 讀取但禁止修改。讀取的是最新提交數據;若行被未提交事務佔用,將阻塞直到該事務結束。
在讀取行上設置排他鎖。阻止其他 Session 讀取或寫入該行數據。
隔離級別:REPEATABLE-READ (RR)
| 場景 | Session 1 | Session 2 | 結果分析 |
|---|---|---|---|
| 1. 普通 SELECT | UPDATE t1 SET b='z' WHERE a=1(未提交) |
SELECT * FROM t1 WHERE a=1 |
返回 Session 1 提交前的快照數據(MVCC 特性) |
| 2. LOCK IN SHARE MODE | UPDATE t1 SET b='y' WHERE a=1(未提交) |
SELECT * FROM t1 WHERE a=1 LOCK IN SHARE MODE |
阻塞等待,直到 Session 1 提交或回滾(共享鎖與排他鎖互斥) |
| 3. FOR UPDATE | UPDATE t1 SET b='x' WHERE a=1(未提交) |
SELECT * FROM t1 WHERE a=1 FOR UPDATE |
阻塞等待,直到 Session 1 提交或回滾(排他鎖與排他鎖互斥) |
結論:RR 級別下,UPDATE 給行加排他鎖;普通 SELECT 讀快照;LOCK IN SHARE MODE 與 FOR UPDATE 均需等待排他鎖釋放。
| 步驟 | Session 1 | Session 2 | 結果 |
|---|---|---|---|
| 1 | BEGIN | BEGIN | - |
| 2 | SELECT * FROM t1 WHERE a=1 FOR UPDATE | - | Session 1 獲得排他鎖 |
| 3 | - | UPDATE t1 SET b='u' WHERE a=1 | 阻塞,等待 Session 1 提交/回滾 |
| 4 | - | SELECT ... FOR UPDATE / LOCK IN SHARE MODE | 無返回,持續等待 |
| 5 | COMMIT | - | Session 1 釋放鎖 |
| 6 | - | 獲得查詢結果,顯示 b='u' | Session 2 繼續執行 |
| 7 | UPDATE t1 SET b='w' WHERE a=1 | - | Session 1 新事務獲鎖 |
| 8 | - | SELECT ... FOR UPDATE / LOCK IN SHARE MODE | 阻塞,等待 Session 1 |
| 9 | COMMIT | - | Session 1 釋放鎖 |
| 10 | - | 獲得結果,顯示 b='w' | Session 2 完成 |
| 步驟 | Session 1 | Session 2 | 結果 |
|---|---|---|---|
| 1 | BEGIN | - | - |
| 2 | SELECT ... LOCK IN SHARE MODE → 返回數據 | - | Session 1 持有共享鎖 |
| 3 | - | BEGIN | - |
| 4 | - | SELECT ... LOCK IN SHARE MODE → 返回數據 | Session 2 也獲得共享鎖(共享鎖兼容) |
| 5 | UPDATE t1 SET b='m' WHERE a=1 | - | 阻塞,等待 Session 2 釋放共享鎖 |
| 6 | - | COMMIT | Session 2 釋放鎖,Session 1 UPDATE 成功 |
| 7 | SELECT ... LOCK IN SHARE MODE | - | 阻塞,等待 Session 1 提交 |
| 8 | COMMIT | - | Session 1 釋放鎖 |
| 9 | - | 獲得結果,顯示 b='m' | Session 2 完成 |
| 當前持有鎖 \ 請求鎖 | SELECT (快照) | LOCK IN SHARE MODE (共享鎖) | FOR UPDATE (排他鎖) | DML (排他鎖) |
|---|---|---|---|---|
| SELECT (快照) | 兼容 | 兼容 | 兼容 | 兼容 |
| LOCK IN SHARE MODE (共享鎖) | 兼容 | 兼容 | 互斥等待 | 互斥等待 |
| FOR UPDATE (排他鎖) | 兼容 | 互斥等待 | 互斥等待 | 互斥等待 |
| DML (排他鎖) | 兼容 | 互斥等待 | 互斥等待 | 互斥等待 |
關鍵洞察:RR 隔離級別下,普通 SELECT 讀取 MVCC 快照不加鎖;鎖操作(共享/排他)僅在顯式指定 LOCK IN SHARE MODE 或 FOR UPDATE 時產生,且與 DML 排他鎖互斥。