資料庫是多使用者共享的資源。當多個交易並發存取相同資料時,若缺乏並發控制,將導致 髒讀、不可重複讀、幻讀 等問題,破壞資料庫一致性。鎖機制正是解決此問題的核心技術——透過限制對資料物件的並發操作,確保交易的 ACID 特性。
| 鎖類型 | 代碼 | 行為 | 相容性 | |
|---|---|---|---|---|
| 共享鎖 | S Lock | 允許其他交易讀取,禁止修改 | 與 S 鎖相容,與 X 鎖衝突 | |
| 排他鎖 | X Lock | 禁止其他交易讀取與修改 | 與任何鎖皆衝突 |
| 值 | 模式代碼 | 鎖模式名稱 | 描述 | 觸發 SQL 操作 |
|---|---|---|---|---|
| 0 | NONE | 無鎖 | - | - |
| 1 | NULL | 空鎖 | 無實際限制 | SELECT |
| 2 | SS (Row-S) | 行級共享鎖 | 允許查詢,禁止排他鎖 | SELECT FOR UPDATE, LOCK TABLE ... IN ROW SHARE MODE |
| 3 | SX (Row-X) | 行級排他鎖 | 允許查詢,禁止 DML | INSERT, UPDATE, DELETE, LOCK TABLE ... IN ROW EXCLUSIVE MODE |
| 4 | S | 共享鎖 | 允許查詢,禁止任何 DML | LOCK TABLE ... IN SHARE MODE |
| 5 | SSX | 共享排他鎖 | 僅允許查詢 | LOCK TABLE ... IN SHARE ROW EXCLUSIVE MODE |
| 6 | X | 排他鎖 | 完全獨佔 | LOCK TABLE ... IN EXCLUSIVE MODE, DDL 操作 |
當執行 DML 時:
SELECT
s.sid, s.serial#, s.username,
l.type, l.lmode, l.request,
o.object_name,
DECODE(l.lmode, 0,'NONE',1,'NULL',2,'ROW-S',3,'ROW-X',4,'SHARE',5,'S/ROW-X',6,'EXCLUSIVE') held_mode,
DECODE(l.request, 0,'NONE',1,'NULL',2,'ROW-S',3,'ROW-X',4,'SHARE',5,'S/ROW-X',6,'EXCLUSIVE') requested_mode
FROM v$lock l
JOIN v$session s ON l.sid = s.sid
LEFT JOIN dba_objects o ON l.id1 = o.object_id
WHERE l.request > 0 OR l.lmode > 0
ORDER BY s.sid;
SELECT
blocking_session,
sid,
seconds_in_wait,
wait_class,
event
FROM v$session
WHERE blocking_session IS NOT NULL;
| 場景 | 現象 | 解決方案 |
|---|---|---|
| 未提交的大量 DML | 大量 Row-X 鎖導致其他 DML 等待 | 縮短交易長度、批次提交、優化索引減少掃描範圍 |
| 外鍵無索引 | 父表刪除/更新導致子表全表鎖 | 為外鍵欄位建立索引 |
| 不當的 LOCK TABLE | 人為加鎖過度 | 避免使用 EXCLUSIVE 模式,改用 ROW SHARE/ROW EXCLUSIVE |
| 位圖索引並發 | 大量鎖衝突 | OLTP 環境避免位圖索引,改用 B-tree |
SELECT ... FOR UPDATE SKIP LOCKED (11g+)鎖機制是 Oracle 並發控制的基石。深入理解 TM/TX 鎖模式、相容性矩陣與常見爭用場景,能幫助 DBA 與開發人員從根源上預防效能瓶頸,設計出高並發、高可用的資料庫應用系統。