环境准备
表t
create table t (id number,name varchar2(10));
事务一(040006001B020000)
insert
1 a
2 b
事务二(03000B00CE020000)
update
1 a1
2 b1
insert
3 c
事务三(03000400CE020000)
update
1 a12
insert
4 d
SQL> select * from t;
ID NAME
---------- ----------
1 a12
2 b1
3 c
4 d
通过分析,事务三,依赖于事务二的处理结果
事务三,update,是在事务二UPDATE结果之上,双连接了字符串'2'
如果取消事务二,会有什么样结果
1.根据默认的处理方式(nocascade)来闪回事务二
SQL> declare
2 v_xid xid_array;
3 begin
4 v_xid := sys.xid_array('03000B00CE020000');
5 dbms_flashback.transaction_backout(1,v_xid);
6 end;
7 /
declare
*
ERROR at line 1:
ORA-55504: Transaction conflicts in NOCASCADE mode
ORA-06512: at "SYS.DBMS_FLASHBACK", line 37
ORA-06512: at "SYS.DBMS_FLASHBACK", line 70
ORA-06512: at line 5
提示,在Nocascade的模式下,无法处理这种事务间的依赖关系
NOCASCADE只能处理不存在依赖关系的事务,事务是独立的,不与其它事务有任何关系
可以使用默认的NOCASCADE方式进行闪回
2.使用cascade方式,来闪回事务二(注意当要闪回A时,如果有事务B是关联A的,当利用cascade闪回A时,就会连B一起闪回,但是闪回B时是不闪回A的)
declare
v_xid xid_array;
begin
v_xid := sys.xid_array('03000B00CE020000');
dbms_flashback.transaction_backout(1,v_xid,dbms_flashback.cascade);
end;
/
SQL> select * from scott.t;
ID NAME
---------- ----------
1 a
2 b
CASCADE方式,是在闪回事务二的同时,同步的闪回了所有依赖于事务二的事务,即事务三也同步的被闪回
所以,查询到的,是只有事务一执行之后的结果
3.使用nonconflict_only,来闪回事务二
SQL> declare
2 v_xid xid_array;
3 begin
4 v_xid := sys.xid_array('03000B00CE020000');
5 dbms_flashback.transaction_backout(1,v_xid,dbms_flashback.NONCONFLICT_ONLY);
6 end;
7 /
PL/SQL procedure successfully completed.
SQL> select * from scott.t;
ID NAME
---------- ----------
1 a12
2 b
4 d
NOCONFLICT_ONLY方式,只闪回没有冲突的行
被以后的事务所引用的行,会跳过,不参与闪回
1 a1,被事务三引用了,不参与闪回
2 b1,事务三没有引用,参与闪回,变成事务一执行完之后的结果 2 b
3 c,没有被之后事务引用,参与闪回,消失
所以最终的结果即上图所示。