Oracle 事务与锁机制

Oracle 事务与锁机制

适用版本:Oracle Database 9i / 10g / 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07


1. 概述

事务(Transaction) 是数据库操作的最小逻辑单元[1],锁(Lock) 保证并发数据一致性。


2. 事务 ACID

属性说明Oracle 实现
原子性全做或全不做undo 段回滚
一致性一致状态转换约束+触发器
隔离性并发互不干扰锁+多版本
持久性提交不丢失redo 日志

3. 事务控制

3.1 基本语句

-- 开始(隐式)
INSERT INTO ...;

-- 提交
COMMIT;

-- 回滚
ROLLBACK;

-- 保存点
SAVEPOINT sp1;
...
ROLLBACK TO sp1;

-- 只读事务
SET TRANSACTION READ ONLY;

-- 读写事务
SET TRANSACTION READ WRITE;

-- 隔离级别
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

3.2 自治事务

CREATE OR REPLACE PROCEDURE log_action(
  p_msg VARCHAR2
) AS
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  INSERT INTO log_table VALUES (p_msg, SYSDATE);
  COMMIT;  -- 仅提交此事务
END;
/

4. 隔离级别

4.1 READ COMMITTED(默认)

-- 读取已提交数据
-- 可能不可重复读、幻读
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

4.2 SERIALIZABLE

-- 完全隔离
-- 可能 ORA-08177 错误
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

4.3 READ ONLY

-- 只读
SET TRANSACTION READ ONLY;

5. 锁类型

5.1 DML 锁

说明模式
TX事务锁排他
TM表锁RS/RX/S/SRX/X

5.2 表锁模式

模式说明兼容
RS(Row Share)行共享大部分
RX(Row Exclusive)行排他RS/RX
S(Share)共享RS/S
SRX(Share Row Exclusive)共享行排他RS
X(Exclusive)排他

5.3 行锁

-- SELECT FOR UPDATE 加行锁
SELECT * FROM employees 
WHERE employee_id = 100 
FOR UPDATE;

-- 等待
SELECT * FROM employees WHERE employee_id = 100 FOR UPDATE WAIT 10;

-- 不等待
SELECT * FROM employees WHERE employee_id = 100 FOR UPDATE NOWAIT;

-- 跳过锁定行
SELECT * FROM employees WHERE dept_id = 10 FOR UPDATE SKIP LOCKED;

5.4 手动加表锁

LOCK TABLE employees IN ROW EXCLUSIVE MODE;
LOCK TABLE employees IN SHARE MODE;
LOCK TABLE employees IN EXCLUSIVE MODE;

6. 锁视图

6.1 查看锁

SELECT 
  s.sid,
  s.serial#,
  s.username,
  l.type,
  l.lmode,
  l.request,
  l.id1,
  l.id2
FROM v$lock l, v$session s
WHERE l.sid = s.sid;

6.2 锁等待

SELECT 
  blocking_session,
  session_id,
  lock_type,
  mode_held,
  mode_requested,
  blocking_username
FROM dba_waiters;

6.3 阻塞链

SELECT 
  LEVEL,
  s.sid,
  s.username,
  s.program,
  s.event
FROM v$session s
START WITH s.blocking_session IS NULL
CONNECT BY PRIOR s.sid = s.blocking_session;

7. 死锁

7.1 死锁示例

会话 1:UPDATE emp SET sal=100 WHERE id=1;
会话 2:UPDATE emp SET sal=200 WHERE id=2;
会话 1:UPDATE emp SET sal=300 WHERE id=2;  -- 等待会话 2
会话 2:UPDATE emp SET sal=400 WHERE id=1;  -- 等待会话 1
-- 死锁!

7.2 Oracle 自动检测

  • 自动检测死锁
  • 回滚一个事务
  • 抛 ORA-00060

7.3 死锁日志

# 查找死锁 trace
$ORACLE_BASE/diag/rdbms/$DB_UNIQUE_NAME/$ORACLE_SID/trace/*ora*.trc

7.4 预防死锁

  • 固定加锁顺序
  • 缩短事务
  • 使用 NOWAIT
  • 批量操作

8. 闩锁(Latch)与 Mutex

8.1 Latch

  • 轻量级锁
  • 保护内存结构
  • 短时间持有

8.2 Mutex

  • 替代部分 Latch
  • 更高效
  • pin 共享

8.3 查看

SELECT name, gets, misses, spin_gets FROM v$latch WHERE misses > 0;
SELECT * FROM v$mutex_sleep_history;

9. 并发问题

9.1 脏读

  • Oracle 不存在(READ COMMITTED 避免)

9.2 不可重复读

-- READ COMMITTED 下可能
SELECT salary FROM emp WHERE id = 100;  -- 5000
-- 其他会话 UPDATE 并 COMMIT
SELECT salary FROM emp WHERE id = 100;  -- 6000

9.3 幻读

-- READ COMMITTED 下可能
SELECT COUNT(*) FROM emp WHERE dept_id = 10;  -- 5
-- 其他会话 INSERT 并 COMMIT
SELECT COUNT(*) FROM emp WHERE dept_id = 10;  -- 6

9.4 隔离级别对比

隔离级别脏读不可重复幻读
READ COMMITTED
SERIALIZABLE
READ ONLY

10. 常见坑与排错

10.1 ORA-00060: 死锁

修复

-- 1. 查看 trace
-- 2. 调整加锁顺序
-- 3. 缩短事务

10.2 ORA-00054: 资源忙

-- NOWAIT 立即失败
SELECT * FROM emp WHERE id=100 FOR UPDATE NOWAIT;

-- 修复:等待或查找阻塞会话
SELECT blocking_session, sid FROM v$session WHERE blocking_session IS NOT NULL;

10.3 阻塞链

-- 查找阻塞源
SELECT 
  s.sid, 
  s.serial#, 
  s.username, 
  s.program, 
  s.event,
  s.seconds_in_wait
FROM v$session s 
WHERE s.sid IN (SELECT blocking_session FROM v$session WHERE blocking_session IS NOT NULL);

-- 杀掉阻塞会话
ALTER SYSTEM KILL SESSION 'sid,serial#';

10.4 锁等待长

-- 1. 缩短事务
-- 2. 优化 SQL
-- 3. 加索引
-- 4. 调整业务逻辑

11. 最佳实践

  1. 事务尽量短:减少锁持有
  2. 按固定顺序加锁:避免死锁
  3. 使用 FOR UPDATE 显式锁定:明确意图
  4. NOWAIT/SKIP LOCKED:避免阻塞
  5. 合理隔离级别:READ COMMITTED 够用
  6. 批量提交:平衡性能
  7. 监控锁等待:及时发现
  8. 加索引:减少锁范围
  9. 避免长事务:影响并发
  10. 自治事务记日志:避免主事务回滚

12. 参考资料

[1] Oracle Database Concepts 19c, “Data Concurrency and Consistency” https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/data-concurrency-and-consistency.html