1、测试用例
declare
begin
INSERT INTO loginuser VALUES('admin','111');
testcommit.test('admin','123456');
end;
2、建表loginuser语句,用来测试用:
CREATE TABLE loginuser (
username varchar(50),
password varchar(50)
)
3、建包testcommit和包体testcommit中的过程test:
create or replace package testcommit is
PROCEDURE test(v_name VARCHAR2,
v_pass VARCHAR2) ;
end testcommit;
、、、、、、、、、、、、、、、、、、、、、、
create or replace package body testcommit is
PROCEDURE test(v_name VARCHAR2,
v_pass VARCHAR2) AS
PRAGMA AUTONOMOUS_TRANSACTION; --增加自主事务
BEGIN
INSERT INTO loginuser VALUES (v_name,v_pass);
COMMIT;--提交事务
END test;
end testcommit;
4、测试结果:
当运行完毕测试用例时,在未提交事务的情况下,loginuser表里的数据只有admin ---123456---一条记录;
INSERT INTO loginuser VALUES('admin','111'); -------此条记录在未提交事务时,并未插入到loginuser表中
testcommit.test('admin','123456');-----------由于使用自主事务,包体内的存储过程已经提交了事务,而且使用了自主事务,所以在测试用例未提交事务的时候,已经插入到了loginuser表里。
5、对比测试:
当修改包体中的存储过程test,把自主事务注释掉,
---注释掉该行 PRAGMA AUTONOMOUS_TRANSACTION; --自主事务
再次针对测试用例测试的结果为:
INSERT INTO loginuser VALUES('admin','111');----在未提交事务的情况下,该条记录成功插入到表loginuer
testcommit.test('admin','123456');---成功插入该记录
在数据清洗时为了方便查看当前运行的状态,特意在存储过程里面添加了一些日志。通过查看日志可以方便的看到当前运行到哪里,但是这输出的日志不能跟过程使用相当的事物(即不管清洗过程是成功还是失败,日志必须得成功写到数据库里面)。Oracle的独立事物就能帮助我们解决这个问题。
下面是方法模型:
procedure AddError(i_runid number, --运行号码
i_append varchar2, --附加信息
i_type number default 10 --错误等级0-9错误,10-99警告
) is
pragma autonomous_transaction;
begin
insert into dw_log_error
(log_id, log_runid, log_type, log_append)
values
(seq_dw_log_errorid.nextval,
i_runid,
i_type,
substr(i_append, 1, 2000));
commit;
end;
只需要在过程内容调整该过程即可!问题立马解决!
在编写程序中,常常需要有些事务提交了,但是有些事务不提交。
典型的应用就是一个主过程调用一个子过程,而子过程主要用于记录日志信息,不论主过程是否失败,子过程都需要执行。
--------主过程---------------
PROCEDURE MAIN
IS
BEGIN
.......
SUB_TRAN;
.........
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
COMMIT;
END MAIN;
------- END SUB---------
如果要完成前文所描述,则SUB_TRAN必须如以下定义
PROCEDURE SUB_TRAN
is
pragma autonomous_transaction;
begin
.......
INSERT INTO LOGTABLE() VALUES();
COMMIT;
EXCEPTION