Linux 环境下 Oracle 事务管理要点
一 事务控制基础
-- 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 结束”。二 隔离级别与一致性
-- 会话级
ALTER SESSION SET ISOLATION_LEVEL = SERIALIZABLE;
-- 仅对下一条事务生效(必须是事务的第一条语句)
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
要点:
三 并发控制与锁
-- 悲观锁:锁定选中行,其他会话不能修改(可加 NOWAIT 避免无限等待)
SELECT id FROM accounts WHERE name = 'A' FOR UPDATE NOWAIT;
四 监控与故障处理
-- 谁在阻塞他人
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 文本
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 锁的超时(秒),默认 0 不等待
ALTER SESSION SET ddl_lock_timeout = 30;
五 实践建议