当前位置:首页 > Oracle > 正文内容

在Oracle中”自治事务”的应用

管理员2年前 (2018-08-29)Oracle610

事务这个概念,对于一个经常使用数据库的人来并不陌生,对于一次有多个步骤操作来说,为保证所影响到的所有数据的完整性,我们都会用事务进行处理,但在实际的软件开发过程中,我们除了要对业务处理之外,还要附加的做一些额外的操作,比如方法访问记录、更新计数器、输出调试信息等等操作,如果这些额外的信息也要记录在数据库中,当事务出现异常而执行回滚操作时,那么所有的额外数据也将被回滚,

那么问题来了,有没有这样的一个方法,可以把业务数据和操作记录分开记录呢,答案是肯定的,并且有多种,比如将额外的数据信息记录在磁盘文件、记录在消息队列中、调用其他接口等形式。

在这里,我们利用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

    分享给朋友:

    相关文章

    发表评论

    访客

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。