温馨提示×

Linux Oracle事务如何管理

小樊
31
2025-12-10 14:54:02
栏目: 云计算

Linux 环境下 Oracle 事务管理要点

一 事务控制基础

  • Linux 上使用 sqlplus / sqlcl / JDBC 连接数据库后,事务遵循标准 SQL:以第一条 DML 开始;执行 COMMIT 提交、执行 ROLLBACK 回滚;未提交前可设置 SAVEPOINT 并回退到指定点;DDL 语句会隐式提交当前事务。示例:
    -- 1) 显式事务边界
    UPDATE accounts SET balance = balance - 100 WHERE name = 'A';
    UPDATE accounts SET balance = balance + 100 WHERE name = 'B';
    COMMIT;  -- 或 ROLLBACK;
    
    -- 2) 保存点
    SAVEPOINT sp_before_b;
    UPDATE accounts SET balance = balance + 100 WHERE name = 'B';
    -- 发现异常:仅回退到保存点
    ROLLBACK TO sp_before_b;
    COMMIT;
    
    以上语义与平台无关,关键在于理解“事务以第一条 DML 开始、以 COMMIT/ROLLBACK 结束”。

二 隔离级别与一致性

  • Oracle 默认隔离级别为 READ COMMITTED;也支持 SERIALIZABLE。设置方式:
    -- 会话级
    ALTER SESSION SET ISOLATION_LEVEL = SERIALIZABLE;
    
    -- 仅对下一条事务生效(必须是事务的第一条语句)
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    
    要点:
    • READ COMMITTED 下,查询只能看到本事务开始前已提交的数据;可能出现不可重复读幻读
    • SERIALIZABLE 下,事务看到的是事务开始时的一致性快照,可避免脏读、不可重复读与幻读,但并发冲突与“无法序列化”错误概率更高。
    • 设置事务级隔离级别时,必须是事务的第一条语句,否则会报错(如 ORA-01453)。

三 并发控制与锁

  • 行级写不阻塞读:读操作利用 Undo 实现多版本读一致性,写只锁定涉及的行,避免“读阻塞写、写阻塞读”的常见问题。
  • 显式加锁以控制竞争:
    -- 悲观锁:锁定选中行,其他会话不能修改(可加 NOWAIT 避免无限等待)
    SELECT id FROM accounts WHERE name = 'A' FOR UPDATE NOWAIT;
    
  • 表级锁模式(TM)与并发度:
    • ROW EXCLUSIVE (RX/SX):DML 默认,允许多会话并发 DML,但会阻塞冲突的 DDL。
    • SHARE (S):允许多会话共享读,但更新受限。
    • EXCLUSIVE (X):最强限制,禁止其他会话任何 DML。
  • 外键未加索引易引发全表扫描与锁升级、并发下降,建议为外键列建立索引。

四 监控与故障处理

  • 识别阻塞与锁等待:
    -- 谁在阻塞他人
    SELECT * FROM dba_blockers;
    
    -- 谁在等待,等待何资源
    SELECT * FROM dba_waiters;
    
    -- 会话级阻塞关系
    SELECT s.SID, s.USERNAME, s.BLOCKING_SESSION_STATUS, s.BLOCKING_SESSION
    FROM v$session s
    WHERE s.BLOCKING_SESSION_STATUS = 'VALID';
    
  • 定位 SQL 与对象:
    -- 通过持有/等待会话定位 SQL 文本
    SELECT /*+ ORDERED */ sql_text
    FROM v$sqltext a
    WHERE (a.hash_value, a.address) IN (
      SELECT DECODE(sql_hash_value, 0, prev_hash_value, sql_hash_value),
             DECODE(sql_hash_value, 0, prev_sql_addr, sql_address)
      FROM v$session b, dba_blockers c
      WHERE b.SID = c.holding_session
    );
    
  • DDL 与 DML 冲突的等待控制:
    -- 设置 DDL 等待 DML 锁的超时(秒),默认 0 不等待
    ALTER SESSION SET ddl_lock_timeout = 30;
    
  • 死锁由 Oracle 自动检测并回滚其中一个事务,应用应捕获异常并重试逻辑。

五 实践建议

  • 事务尽量短小精悍:尽快提交,减少锁持有时间,降低冲突与回滚成本。
  • 业务边界划分事务;复杂流程用 SAVEPOINT 做局部回退,避免全事务重做。
  • 高并发更新同一行时,先以 SELECT … FOR UPDATE 锁定候选行,再计算与更新,减少丢失更新。
  • 读多写少场景优先 READ COMMITTED;需要强一致性且可接受冲突/重试时再用 SERIALIZABLE
  • 外键与高频 JOIN 列建立合适索引,避免全表扫描与锁升级,提升并发与稳定性。

0