前几天项目上线出现了一个很头疼的问题,测试环境完全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操作。