本文档风哥主要介绍Oracle数据库事务管理相关知识,包括Oracle数据库事务的概念、Oracle数据库事务的特性、Oracle数据库事务的隔离级别、Oracle数据库事务的控制语句、Oracle数据库事务的监控、Oracle数据库事务的优化等内容,由风哥教程参考Oracle官方文档Administration内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。
Part01-基础概念与理论知识
1.1 Oracle数据库事务的概念
Oracle数据库事务(Transaction)是由一条或多条SQL语句组成的逻辑工作单元,这些SQL语句作为一个整体要么全部执行成功,要么全部执行失败。事务是数据库管理系统的基本执行单元,用于保证数据的一致性和完整性。更多视频教程www.fgedu.net.cn
1.2 Oracle数据库事务的ACID特性
Oracle数据库事务具有ACID特性:
- 原子性(Atomicity):事务中的所有操作要么全部成功,要么全部失败
- 一致性(Consistency):事务执行前后,数据库从一个一致性状态转换到另一个一致性状态
- 隔离性(Isolation):多个事务并发执行时,彼此之间互不干扰
- 持久性(Durability):事务提交后,对数据的修改是永久性的
1.3 Oracle数据库事务的隔离级别
Oracle数据库支持的事务隔离级别:
- 读未提交(Read Uncommitted):允许读取未提交的数据,存在脏读、不可重复读、幻读问题
- 读已提交(Read Committed):只能读取已提交的数据,默认隔离级别
- 可重复读(Repeatable Read):同一事务中多次读取同一数据结果一致
- 串行化(Serializable):最高隔离级别,完全隔离事务
Part02-生产环境规划与建议
2.1 Oracle数据库事务规划
Oracle数据库事务规划要点:
– 事务尽量短小精悍,避免长时间运行
– 按相同顺序访问对象,减少死锁风险
– 合理设置事务大小,平衡性能和一致性
– 及时提交或回滚事务,释放资源
– 使用合适的隔离级别,根据业务需求选择
# 事务相关参数规划
– TRANSACTIONS:控制并发事务数量,通常设置为SESSIONS的1.1倍
– ROLLBACK_SEGMENTS:指定回滚段(11g及之前版本)
– UNDO_MANAGEMENT:设置为AUTO使用自动撤销管理
– UNDO_TABLESPACE:指定撤销表空间
– UNDO_RETENTION:设置撤销数据保留时间(秒)
# 事务超时规划
– 长事务阈值:超过5分钟的事务需要关注
– 空闲事务阈值:超过30分钟的空闲事务需要清理
– 事务大小阈值:修改超过100万行的事务需要拆分
2.2 Oracle数据库事务最佳实践
Oracle数据库事务最佳实践:
1. 事务边界清晰,逻辑明确
2. 事务尽量短小,避免长时间持有锁
3. 避免在事务中进行用户交互
4. 及时提交或回滚,释放资源
5. 使用批量操作,减少事务数量
6. 合理使用保存点,灵活控制事务
7. 避免大事务,拆分为多个小事务
8. 监控长事务,及时告警和处理
# 事务处理最佳实践
1. 使用异常处理,确保事务正确结束
2. 合理设置重试机制,处理临时失败
3. 使用日志记录,便于问题排查
4. 考虑并发场景,避免事务冲突
5. 定期review事务设计,持续优化
2.3 Oracle数据库事务优化建议
Oracle数据库事务优化建议:
- 优化事务大小:事务尽量短小,避免大事务
- 使用批量操作:合理使用批量操作,减少事务数量
- 合理使用索引:减少锁定的行数,提高并发
- 避免全表扫描:使用索引,减少锁范围
- 及时提交:事务完成后及时提交,释放资源
- 监控长事务:及时发现和处理长事务
Part03-生产环境项目实施方案
3.1 Oracle数据库事务控制语句
3.1.1 Oracle数据库事务开始
SQL> connect sys/oracle as sysdba
Connected.
# 查看当前事务状态
SQL> select status from v$transaction;no rows selected
# 执行第一条SQL语句,事务开始
SQL> update fgedu_employees set salary = salary * 1.1 where employee_id = 100;1 row updated.
# 查看当前事务
SQL> select
addr,
xidusn,
xidslot,
xidsqn,
status,
start_time,
used_ublk,
used_urec
from v$transaction;ADDR XIDUSN XIDSLOT XIDSQN STATUS START_TIME USED_UBLK USED_UREC
—————- ———- ———- ———- ——– ——————– ———- ———-
0000000087654321 1 23 4567 ACTIVE 03/31/26 10:00:00 1 1
# 提交事务
SQL> commit;Commit complete.
# 查看事务状态
SQL> select status from v$transaction;no rows selected
3.1.2 Oracle数据库事务提交和回滚
SQL> update fgedu_employees set salary = salary * 1.1 where employee_id = 100;1 row updated.
SQL> commit;Commit complete.
# 验证修改
SQL> select salary from fgedu_employees where employee_id = 100;SALARY
———-
11000
# 回滚事务
SQL> update fgedu_employees set salary = salary * 1.1 where employee_id = 100;1 row updated.
SQL> rollback;Rollback complete.
# 验证回滚
SQL> select salary from fgedu_employees where employee_id = 100;SALARY
———-
11000
# 自动提交(不推荐在生产环境使用)
SQL> set autocommit on;SQL> update fgedu_employees set salary = salary * 1.1 where employee_id = 100;1 row updated.
Commit complete.
# 关闭自动提交
SQL> set autocommit off;
3.2 Oracle数据库保存点使用
3.2.1 Oracle数据库保存点创建和使用
SQL> update fgedu_employees set salary = salary * 1.1 where employee_id = 100;1 row updated.
SQL> savepoint sp1;Savepoint created.
SQL> update fgedu_employees set salary = salary * 1.1 where employee_id = 200;1 row updated.
SQL> savepoint sp2;Savepoint created.
SQL> update fgedu_employees set salary = salary * 1.1 where employee_id = 300;1 row updated.
# 回滚到保存点sp2
SQL> rollback to savepoint sp2;Rollback complete.
# 验证回滚结果
SQL> select salary from fgedu_employees where employee_id in (100, 200, 300);SALARY
———-
12100
12100
10000
# 回滚到保存点sp1
SQL> rollback to savepoint sp1;Rollback complete.
# 验证回滚结果
SQL> select salary from fgedu_employees where employee_id in (100, 200, 300);SALARY
———-
12100
11000
10000
# 提交剩余事务
SQL> commit;Commit complete.
3.2.2 Oracle数据库只读事务
SQL> set transaction read only;Transaction set.
# 只能执行查询,不能执行DML
SQL> select * from fgedu_employees where employee_id = 100;EMPLOYEE_ID EMP_NAME EMP_EMP_EMP_LAST_NAME SALARY
———– ———- ———- ———-
100 Steven King 12100
# 尝试执行DML会报错
SQL> update fgedu_employees set salary = salary * 1.1 where employee_id = 100;update fgedu_employees set salary = salary * 1.1 where employee_id = 100
*
ERROR at line 1:
ORA-01456: may not perform in-place update operations inside READ ONLY transaction
# 结束只读事务
SQL> commit;Commit complete.
# 设置串行化事务
SQL> set transaction isolation level serializable;Transaction set.
# 执行查询和DML
SQL> select * from fgedu_employees where employee_id = 100;EMPLOYEE_ID EMP_NAME EMP_EMP_EMP_LAST_NAME SALARY
———– ———- ———- ———-
100 Steven King 12100
SQL> update fgedu_employees set salary = salary * 1.1 where employee_id = 100;1 row updated.
SQL> commit;Commit complete.
3.3 Oracle数据库事务监控方法
3.3.1 Oracle数据库查看当前事务
SQL> select
addr,
xidusn,
xidslot,
xidsqn,
status,
start_time,
used_ublk,
used_urec,
log_io,
phy_io
from v$transaction
order by start_time;ADDR XIDUSN XIDSLOT XIDSQN STATUS START_TIME USED_UBLK USED_UREC LOG_IO PHY_IO
—————- ———- ———- ———- ——– ——————– ———- ———- ———- ———-
0000000087654321 1 23 4567 ACTIVE 03/31/26 10:00:00 5 10 100 5
0000000087654322 2 34 5678 ACTIVE 03/31/26 10:05:00 2 3 20 1
# 查看事务对应的会话
SQL> select
s.sid,
s.serial#,
s.username,
s.status,
s.program,
s.machine,
s.sql_id,
t.start_time,
t.used_ublk,
t.used_urec
from v$session s, v$transaction t
where s.taddr = t.addr
order by t.start_time;SID SERIAL# USERNAME STATUS PROGRAM MACHINE SQL_ID START_TIME USED_UBLK USED_UREC
———- ———- ———- ——– —————– ————- ————- ——————– ———- ———-
123 45678 FGAPP_USER ACTIVE app.exe server1 abc123def456 03/31/26 10:00:00 5 10
124 45679 FGAPP_USER ACTIVE app.exe server1 def456abc123 03/31/26 10:05:00 2 3
# 查看长事务(超过5分钟)
SQL> select
s.sid,
s.serial#,
s.username,
s.program,
s.machine,
t.start_time,
round((sysdate – to_date(t.start_time, ‘MM/DD/RR HH24:MI:SS’)) * 1440, 2) as duration_min,
t.used_ublk,
t.used_urec
from v$session s, v$transaction t
where s.taddr = t.addr
and (sysdate – to_date(t.start_time, ‘MM/DD/RR HH24:MI:SS’)) * 1440 > 5
order by duration_min desc;SID SERIAL# USERNAME PROGRAM MACHINE START_TIME DURATION_MIN USED_UBLK USED_UREC
———- ———- ———- —————– ————- ——————– ———— ———- ———-
123 45678 FGAPP_USER app.exe server1 03/31/26 09:50:00 15.00 5 10
3.3.2 Oracle数据库查看事务详情
SQL> select
s.sid,
s.serial#,
s.username,
s.sql_id,
sq.sql_text
from v$session s, v$sql sq
where s.sql_id = sq.sql_id
and s.taddr is not null;SID SERIAL# USERNAME SQL_ID SQL_TEXT
———- ———- ———- ————- —————————————-
123 45678 FGAPP_USER abc123def456 BEGIN
update fgedu_employees set salary = salar
y * 1.1 where department_id = 10;– 一些处理
update fgedu_departments set budget = bud
get * 1.1 where department_id = 10;END;# 查看事务等待
SQL> select
s.sid,
s.serial#,
s.username,
s.event,
s.wait_class,
s.seconds_in_wait,
s.state
from v$session s
where s.taddr is not null
and s.state = ‘WAITING’;SID SERIAL# USERNAME EVENT WAIT_CLASS SECONDS_IN_WAIT STATE
———- ———- ———- —————————— ————— ————— ——————-
124 45679 FGAPP_USER enq: TX – row lock contention Application 120 WAITING
# 查看事务锁定的对象
SQL> select
s.sid,
s.serial#,
s.username,
o.object_name,
o.object_type,
l.lmode,
l.request
from v$session s,
v$lock l,
v$locked_object lo,
dba_objects o
where s.taddr = l.addr
and s.sid = lo.session_id
and lo.object_id = o.object_id
order by s.sid;SID SERIAL# USERNAME OBJECT_NAME OBJECT_TYPE LMODE REQUEST
———- ———- ———- —————————— ———— ———- ———-
123 45678 FGAPP_USER FGEDU_EMPLOYEES TABLE 3 0
123 45678 FGAPP_USER FGEDU_DEPARTMENTS TABLE 3 0
Part04-生产案例与实战讲解
4.1 Oracle数据库事务异常处理
在Oracle数据库事务管理过程中,可能会遇到以下问题:
4.1.1 Oracle数据库事务回滚失败
# 分析步骤:
# 1. 查看告警日志
$ tail -n 100 /oracle/app/oracle/diag/rdbms/fgedudb/fgedudb/trace/alert_fgedudb.log
# 2. 查看回滚段状态
SQL> select
segment_name,
status,
tablespace_name,
extents,
bytes
from dba_rollback_segs
order by segment_name;SEGMENT_NAME STATUS TABLESPACE_NAME EXTENTS BYTES
——————– ——— —————- ———- ———-
SYSTEM ONLINE SYSTEM 5 5242880
_SYSSMU1_123456789$ ONLINE UNDOTBS1 10 10485760
_SYSSMU2_234567890$ ONLINE UNDOTBS1 8 8388608
# 3. 查看UNDO表空间使用情况
SQL> select
tablespace_name,
sum(bytes)/1024/1024 as total_mb,
sum(decode(status, ‘ACTIVE’, bytes, 0))/1024/1024 as active_mb,
sum(decode(status, ‘UNEXPIRED’, bytes, 0))/1024/1024 as unexpired_mb,
sum(decode(status, ‘EXPIRED’, bytes, 0))/1024/1024 as expired_mb
from dba_undo_extents
group by tablespace_name;TABLESPACE_NAME TOTAL_MB ACTIVE_MB UNEXPIRED_MB EXPIRED_MB
——————– ———- ———- ———— ———-
UNDOTBS1 100 20 50 30
# 4. 处理方案
# 方案1:增加UNDO表空间大小
SQL> alter tablespace undotbs1 add datafile ‘/oradata/fgedudb/undotbs02.dbf’ size 100M autoextend on next 100M maxsize 10G;Tablespace altered.
# 方案2:增加UNDO_RETENTION时间
SQL> alter system set undo_retention = 3600 scope=both;System altered.
# 方案3:优化事务,减少事务大小和持续时间
# 5. 预防措施
# – 确保UNDO表空间足够大
# – 合理设置UNDO_RETENTION参数
# – 优化事务设计,避免大事务和长事务
# – 监控UNDO表空间使用情况
4.2 Oracle数据库长事务处理
# 分析步骤:
# 1. 查看长事务
SQL> select
s.sid,
s.serial#,
s.username,
s.program,
s.machine,
s.sql_id,
t.start_time,
round((sysdate – to_date(t.start_time, ‘MM/DD/RR HH24:MI:SS’)) * 1440, 2) as duration_min,
t.used_ublk,
t.used_urec
from v$session s, v$transaction t
where s.taddr = t.addr
and (sysdate – to_date(t.start_time, ‘MM/DD/RR HH24:MI:SS’)) * 1440 > 60
order by duration_min desc;SID SERIAL# USERNAME PROGRAM MACHINE SQL_ID START_TIME DURATION_MIN USED_UBLK USED_UREC
———- ———- ———- —————– ————- ————- ——————– ———— ———- ———-
123 45678 FGAPP_USER app.exe server1 abc123def456 03/31/26 08:00:00 120.00 100 1000
# 2. 查看长事务执行的SQL
SQL> select sql_text from v$sql where sql_id = ‘abc123def456’;SQL_TEXT
——————————————————————————–
BEGIN
FOR i IN 1..1000000 LOOP
UPDATE fgedu_employees SET salary = salary * 1.01 WHERE employee_id = i;COMMIT;END LOOP;END;# 3. 分析长事务原因
# – 循环中每次都提交,虽然事务小,但数量多,总时间长
# – 可以使用批量操作优化
# 4. 处理方案
# 方案1:联系应用负责人,优化事务
# 方案2:如果业务允许,终止长事务
SQL> alter system kill session ‘123,45678’;System altered.
# 5. 优化后的事务
BEGIN
UPDATE fgedu_employees SET salary = salary * 1.01 WHERE employee_id BETWEEN 1 AND 1000000;COMMIT;END;/# 6. 预防措施
# – 优化事务设计,使用批量操作
# – 监控长事务,及时告警
# – 设置事务超时机制
# – 定期review事务设计
4.3 Oracle数据库事务问题解决方案
Oracle数据库事务问题的常见解决方案:
- 优化事务设计:事务尽量短小,使用批量操作
- 合理使用保存点:灵活控制事务,避免全部回滚
- 监控长事务:及时发现和处理长事务
- 优化UNDO配置:确保UNDO表空间足够,合理设置UNDO_RETENTION
- 使用合适的隔离级别:根据业务需求选择隔离级别
- 异常处理:使用异常处理机制,确保事务正确结束
Part05-风哥经验总结与分享
5.1 Oracle数据库事务管理最佳实践
Oracle数据库事务管理最佳实践:
- 事务设计:事务尽量短小精悍,逻辑清晰
- 批量操作:合理使用批量操作,减少事务数量
- 及时提交:事务完成后及时提交或回滚
- 保存点使用:合理使用保存点,灵活控制事务
- 监控告警:配置事务监控和告警,及时发现问题
- 异常处理:使用异常处理,确保事务正确结束
- 定期分析:定期分析事务运行情况,持续优化
5.2 Oracle数据库事务检查清单
– [ ] 事务设计遵循最佳实践
– [ ] 事务尽量短小精悍
– [ ] 使用批量操作,减少事务数量
– [ ] 及时提交或回滚事务
– [ ] 合理使用保存点
– [ ] UNDO表空间配置合理
– [ ] UNDO_RETENTION设置合适
– [ ] 配置事务监控和告警
– [ ] 定期分析事务运行情况
– [ ] 及时处理长事务
– [ ] 使用异常处理机制
– [ ] 定期review事务设计
# 事务问题处理流程
1. 发现事务问题
2. 收集事务相关信息
3. 分析事务问题原因
4. 制定处理方案
5. 执行处理方案
6. 验证问题解决
7. 总结经验,优化预防措施
5.3 Oracle数据库事务管理工具推荐
Oracle数据库事务管理常用工具:
- v$transaction:查看当前事务信息
- v$session:查看会话信息,关联事务
- v$rollstat:查看回滚段统计信息
- v$undostat:查看UNDO统计信息
- dba_undo_extents:查看UNDO区使用情况
- 告警日志:查看事务相关错误
- Oracle Enterprise Manager:图形化事务监控和管理
- AWR/ASH报告:分析历史事务情况
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
