Oracle 事务与并发控制详解

Oracle 事务与并发控制详解

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


1. 概述

事务与并发控制是数据库核心[1]:

详细见:Oracle 事务与锁机制


2. ACID

- Atomicity(原子性)
- Consistency(一致性)
- Isolation(隔离性)
- Durability(持久性)

3. 事务

3.1 开始

- 隐式:第一条 DML
- 显式:SET TRANSACTION

3.2 结束

- COMMIT
- ROLLBACK
- DDL(自动提交)
- 异常退出(回滚)

3.3 控制

-- 提交
COMMIT;
COMMIT WORK;
COMMIT COMMENT 'msg';

-- 回滚
ROLLBACK;
ROLLBACK TO savepoint;

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

4. 隔离级别

4.1 支持

- READ COMMITTED(默认)
- SERIALIZABLE
- READ ONLY

4.2 设置

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET TRANSACTION READ ONLY;

ALTER SESSION SET ISOLATION_LEVEL = SERIALIZABLE;

4.3 现象

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

5. 锁

5.1 类型

- DML 锁:TM(表)、TX(行)
- DDL 锁:独占、共享、断
- Latch:内部
- Mutex:内部

5.2 DML 锁

-- 行锁(TX)
UPDATE employees SET salary = 5000 WHERE id = 100;
-- 表锁(TM)

5.3 锁模式

模式说明
RSRow Share
RXRow Exclusive
SShare
SRXShare Row Exclusive
XExclusive

5.4 加锁

-- 显式
LOCK TABLE employees IN ROW EXCLUSIVE MODE;
LOCK TABLE employees IN EXCLUSIVE MODE;

-- FOR UPDATE
SELECT * FROM employees WHERE id = 100 FOR UPDATE;
SELECT * FROM employees WHERE id = 100 FOR UPDATE NOWAIT;
SELECT * FROM employees WHERE id = 100 FOR UPDATE WAIT 10;
SELECT * FROM employees FOR UPDATE SKIP LOCKED;

5.5 查看

SELECT sid, type, lmode, request, id1, id2 
FROM v$lock 
WHERE sid = ...;

SELECT sid, serial#, username, blocking_session 
FROM v$session 
WHERE blocking_session IS NOT NULL;

详细见:Oracle 锁与闩锁诊断


6. 一致性读

6.1 MVCC

- 多版本
- UNDO 段
- SCN

6.2 查询

- 一致性点
- 当前 + UNDO
- 无阻塞读

6.3 ORA-01555

- Snapshot too old
- UNDO 不足
- 增大 UNDO

详细见:Oracle Undo 与 Redo 调优


7. 死锁

7.1 触发

- 循环等待
- Oracle 自动检测
- ORA-00060

7.2 避免

- 一致顺序
- 短事务
- 索引(避免全表锁)
- 索引外键

7.3 诊断

-- trace 文件
SELECT * FROM v$diag_info WHERE name = 'Default Trace File';

-- 查看死锁
SHOW PARAMETER deadlock;

8. 自治事务

8.1 定义

CREATE OR REPLACE PROCEDURE log_msg(p_msg VARCHAR2) IS
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  INSERT INTO log VALUES (p_msg, SYSTIMESTAMP);
  COMMIT;
END;
/

8.2 用途

- 日志
- 审计
- 独立提交
- 不影响主事务

详细见:Oracle 存储过程与函数详解


9. 分布式事务

9.1 两阶段提交

1. PREPARE
2. COMMIT

9.2 处理

-- 强制提交/回滚
COMMIT FORCE 'trans_id';
ROLLBACK FORCE 'trans_id';

-- 查看悬挂
SELECT * FROM dba_2pc_pending;

9.3 XA

- Java JTA
- 跨资源
- 协调

10. 提交

10.1 选项

-- 快速
COMMIT FAST;  -- 默认(不写redo)

-- 批处理
COMMIT BATCH;  -- 批量

-- 等待
COMMIT WAIT;  -- 等待LGWR

-- 立即
COMMIT IMMEDIATE;  -- 立即

10.2 COMMIT_WRITE

ALTER SESSION SET COMMIT_WRITE = 'BATCH,NOWAIT';

详细见:Oracle Undo 与 Redo 调优


11. 并发问题

11.1 丢失更新

- 行锁
- FOR UPDATE
- 乐观锁

11.2 不可重复读

- SERIALIZABLE
- 行锁

11.3 幻读

- SERIALIZABLE
- 范围锁

11.4 脏读

- READ COMMITTED 已避免
- 不可脏读

12. 乐观锁

12.1 版本号

CREATE TABLE t (id NUMBER, data VARCHAR2(100), version NUMBER);

UPDATE t SET data = 'new', version = version + 1
WHERE id = 1 AND version = :old_version;

12.2 时间戳

CREATE TABLE t (id NUMBER, data VARCHAR2(100), updated_at TIMESTAMP);

UPDATE t SET data = 'new', updated_at = SYSTIMESTAMP
WHERE id = 1 AND updated_at = :old_ts;

12.3 校验和

- 数据哈希
- 校验

13. 悲观锁

-- 查询并锁定
SELECT * FROM employees WHERE id = 100 FOR UPDATE;

-- 处理
UPDATE employees SET salary = 5000 WHERE id = 100;
COMMIT;

14. 应用场景

14.1 OLTP

- 短事务
- 行锁
- 乐观/悲观
- 一致顺序

14.2 批处理

- 大事务
- 批量提交
- 性能

14.3 报表

- READ ONLY
- 一致性
- 长查询

15. 监控

15.1 锁等待

SELECT sid, serial#, username, blocking_session, event, wait_class
FROM v$session 
WHERE blocking_session IS NOT NULL;

SELECT sid, type, lmode, request, block
FROM v$lock 
WHERE block > 0 OR request > 0;

15.2 等待事件

SELECT event, total_waits, time_waited 
FROM v$system_event 
WHERE event LIKE '%enq%'
ORDER BY time_waited DESC;

详细见:Oracle 等待事件详解


16. 常见坑与排错

16.1 ORA-00060

- 死锁
- trace
- 顺序

16.2 ORA-01555

- UNDO 不足
- 增大
- 优化长查询

16.3 ORA-02049

- 分布式超时
- 调整

16.4 阻塞

- 长事务
- 锁等待
- 终止会话

17. 最佳实践

  1. 短事务:性能
  2. 绑定变量:减少解析
  3. 一致顺序:避免死锁
  4. 索引外键:避免全表锁
  5. 行锁:并发
  6. 乐观锁:低冲突
  7. 悲观锁:高冲突
  8. 隔离级别:需求
  9. 监控:锁等待
  10. 测试:并发

18. 参考资料

[1] Oracle Database Concepts 19c, “Transactions” https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/transactions.html