在Oracle中”自治事务”的应用
事务这个概念,对于一个经常使用数据库的人来并不陌生,对于一次有多个步骤操作来说,为保证所影响到的所有数据的完整性,我们都会用事务进行处理,但在实际的软件开发过程中,我们除了要对业务处理之外,还要附加的做一些额外的操作,比如方法访问记录、更新计数器、输出调试信息等等操作,如果这些额外的信息也要记录在数据库中,当事务出现异常而执行回滚操作时,那么所有的额外数据也将被回滚,
那么问题来了,有没有这样的一个方法,可以把业务数据和操作记录分开记录呢,答案是肯定的,并且有多种,比如将额外的数据信息记录在磁盘文件、记录在消息队列中、调用其他接口等形式。
在这里,我们利用Oracle数据库自身的一个特性,即使用“自治事务”的方法,其英文的描述为 “autonomous_transaction”,自治事务可以单独的定义到一个存储过程中,也可以放在匿名块中直接使用,这种存储过程对数据库的操作并不受调用者事务的控制,就如同运行在一个独立的会话中一样。
下面我们用示例来看一下有何差异。
1、 建立两张测试表,模拟创建一个日志记录表(tlogs)和一个业务表 (tdata)
SQL> create table tlogs(id int, msg varchar(30)); Table created SQL> create table tdata(id int, data varchar(10)); Table created
2、 按正常的方法创建一个存储过程,向日志表写入一条数据。
SQL> create procedure sp_add_logs(p_id int, p_msg varchar2) 2 as 3 begin 4 insert into tlogs(id, msg) values(p_id, p_msg); 5 commit; 6 end; 7 / Procedure created SQL>
3、 创建一个写业务数据的方法,包含两次操作,第一次回滚,第二次提交。
SQL> create procedure sp_add_data 2 as 3 begin 4 delete tlogs; 5 delete tdata; 6 commit; 7 insert into tdata values(100, 'data1'); 8 sp_add_logs(1, 'insert 100'); 9 rollback; 10 sp_add_logs(2, 'rollback 100'); 11 12 insert into tdata values(200,'data2'); 13 sp_add_logs(3, 'insert 200'); 14 commit; 15 sp_add_logs(4, 'commit 200'); 16 end; 17 / Procedure created SQL>
4、 调用一次sp_add_data,再查询业务表和日志表。
SQL> exec sp_add_data; PL/SQL procedure successfully completed SQL> col id format a10; SQL> select * from tlogs order by id; ID MSG ---------- ------------------------------ 2 rollback 100 3 insert 200 4 commit 200 SQL> select * from tdata; ID DATA ---------- ---------- 200 data2 SQL>
可以看到,第一条业务数据被回滚以后,之前向tlogs 表插入的记录也被回滚了,也就是说日志是不完整的。
5、 将日志的存储过程修改为“自治”特性。
SQL> create or replace procedure sp_add_logs(p_id int, p_msg varchar2) 2 as 3 pragma autonomous_transaction; 4 begin 5 insert into tlogs(id, msg) values(p_id, p_msg); 6 commit; 7 end; 8 / Procedure created SQL>
自治事务特性的存储过程,在创建时只需要在as的后面,增加pargma选项,告知编译器。并且,存储过程内部必须要有commit语句,以区别于主事务。
6、 再调用一次sp_add_data,再查询业务表和日志表
SQL> exec sp_add_data; PL/SQL procedure successfully completed SQL> col id format a10; SQL> select * from tlogs order by id; ID MSG ---------- ------------------------------ 1 insert 100 2 rollback 100 3 insert 200 4 commit 200 SQL> select * from tdata; ID DATA ---------- ---------- 200 data2 SQL>
可以看到,在插入业务表后,紧接着就插入一条日志信息,然后又马上执行了回滚操作,但是日志却记录了下来。
7、 使用注意事项
如果自治事务的代码,请求了主事务锁定的资源,就会有死锁发生。
根据ASKTOM的建议,自主事务最好只用来记录日志,不要做其他的用途。
扫描二维码推送至手机访问。
版权声明:本文由卖水果的net发布,如需转载请注明出处。
本文地址:http://www.msgde.net/oracle/oracle_autonomous_transaction.html