天天看点

oracle 自治事务异常不回滚,Oracle自治事务踩坑记录

前几天项目上线出现了一个很头疼的问题,测试环境完全ok,正式环境出现了表更新数据之后sql查询拿不到最新值的问题,存储过程代码片段如下:

--更新状态为“审批中”

UPDATE bid_entrustment_headers h

SET h.status = c_status_approving --审批中

WHERE h.entrustment_header_id = p_entrustment_header_id;

--创建招标书快照

bid_entrustment_history_pkg.create_approve_snap(p_entrustment_header_id => p_entrustment_header_id,

p_user_id               => p_user_id);

在创建招标书快照的时候拿不到上面更新的数据,经排查发现 bid_entrustment_history_pkg.create_approve_snap这个存储过程里用了自治事务语句:PRAGMA AUTONOMOUS_TRANSACTION;(也不知道哪个杀千刀的直接在正式环境上加了这句代码),本来需要保持事务一致性的逻辑处理确不在同一事物当中,导致快照表中数据错误,所以学习了一下oracle的自治事务相关知识,以便日后使用。

一,使用例子

在存储过程中像声明变量一样,插入PRAGMA AUTONOMOUS_TRANSACTION;语句,便可以将当前的存储过程定义为自治事务类型:

--测试自治事务(子自治)

PROCEDURE p_test_at_and_mt_son IS

PRAGMA AUTONOMOUS_TRANSACTION;

cnt NUMBER := -1;

BEGIN

--具体需求逻辑

END;

END;

二,使用效果

自治事务类型的存储过程在被其他程序块调用的时候,相对于其他程序块来说是独立的,也就是说其他程序块的DDL等操作不会影响自治事务类型的存储过程,反之,自治事务中对表的更新或者锁操作也不会影响其他程序块。

这样一定程度上达到了异步效果,但在需要保证事务一致性的情况下并不适用,但对一些特殊需求也很好用,不需要等待mian程序块的commit操作。