事务的依赖性 比如,两个事务TX1和TX2,若符合以下3个条件的任意一个就可以认为TX2依赖TX1:
(1)WAW依赖(Write After Write),即在TX1修改了表的某行之后,TX2又修改了同一行。
(2)主键依赖,即在一张拥有主键的表中TX1首先删除了一行,之后TX2又插入了具有相同主键值的另一行。
(3)外建依赖,即由于TX1的修改(insert或update)而产生了新的可被外键参考的字段值,之后TX2修改(insert或update)外键字段时利用了TX1所产生的字段值。
TRANSACTION_BACKOUT存储过程的OPTIONS参数就是为了解决事务依赖性问题而存在的,在该参数上管理员可以使用4种撤销事务的方案,假设被撤销的事务是TX1,若其具有依赖事务,则称为TX2:
(1)NOCASCADE,TX1不可以被任何其他事务依赖(即TX2不存在),否则撤销操作报错。
(2)CASCADE,将TX1连同TX2一起撤销。
(3)NOCASCADE_FORCE,忽略TX2,直接执行TX1的撤销SQL将TX1撤销,如果没有约束上的冲突,操作将成功,否则约束报错导致撤销操作失败。
(4)NONCONFILICT_ONLY,在不影响TX2的前提下,撤销TX1的修改。与NOCASCADE_FORCE的不同点在于会首先过滤一下TX1的撤销SQL,确保它们不会作用在TX2修改的行上。
如果闪回第一个事务
刚开始:
DEPTNO DNAME LOC
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
事务一之后:
SQL> select * from dept;
DEPTNO DNAME LOC
0 ACCOUNTING NEW YORK
10 RESEARCH DALLAS
20 SALES CHICAGO
30 OPERATIONS BOSTON
事务二之后:
SQL> select * from dept;
DEPTNO DNAME LOC
15 ACCOUNTING NEW YORK
25 RESEARCH DALLAS
35 SALES CHICAGO
45 OPERATIONS BOSTON
闪回事务一之后:
SQL> select * from test1.dept;
DEPTNO DNAME LOC
15 ACCOUNTING NEW YORK
25 RESEARCH DALLAS
35 SALES CHICAGO
45 OPERATIONS BOSTON
闪回事务二之后:
SQL> select * from test1.dept;
DEPTNO DNAME LOC
0 ACCOUNTING NEW YORK
10 RESEARCH DALLAS
20 SALES CHICAGO
30 OPERATIONS BOSTON
实验:
alter database add supplemental log data;
alter database add supplemental log data (primary key) columns;
grant execute on dbms_flashback to test1;
grant select any transaction to test1;
select distinct xid,commit_scn
from flashback_transaction_query
where table_owner=‘TEST1’ and
table_name=‘DEPT’ and
commit_timestamp > systimestamp - interval ‘15’ minute
order by commit_scn;
select undo_sql from flashback_transaction_query
where commit_scn=‘8460526’;
declare
xids sys.xid_array;
begin
xids := sys.xid_array(‘090019005E2C0000’);
dbms_flashback.transaction_backout(1,xids,options=>dbms_flashback.nocascade_force);
end;
/