ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Oracle11新特性——撤销事务(二)

Oracle11新特性——撤销事务(二)

原创 Linux操作系统 作者:yangtingkun 时间:2007-12-18 00:00:00 0 删除 编辑

打算写一系列的文章介绍11g的新特性和变化。

Oracle11g提供了撤销事务的功能,可以撤销一个已经提交的事务。

这一篇介绍撤销级联事务。

Oracle11新特性——撤销事务(一):http://yangtingkun.itpub.net/post/468/419695


上面一篇简单介绍了如何撤销一个事务,那个例子中,被撤销事务和其他事务没有关联。如果撤销一个事务的时候发现被撤销事务和其他事务级联,那么会有多种情况。

SQL> CONN YANGTK/yangtk@172.0.2.61/test11g.netdb已连接。
SQL> CREATE TABLE T_FLASH_TRANS (ID NUMBER, NAME VARCHAR2(30));

表已创建。

SQL> INSERT INTO T_FLASH_TRANS VALUES (1, 'A');

已创建 1 行。

SQL> INSERT INTO T_FLASH_TRANS VALUES (2, 'B');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> UPDATE T_FLASH_TRANS SET NAME = NAME || '1';

已更新2行。

SQL> INSERT INTO T_FLASH_TRANS VALUES (3, 'C');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> UPDATE T_FLASH_TRANS SET NAME = NAME || '2' WHERE ID = 1;

已更新 1 行。

SQL> INSERT INTO T_FLASH_TRANS VALUES (4, 'D');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> CONN SYS/test@172.0.2.61/TEST11G.NETDB AS SYSDBA已连接。
SQL> SELECT XID, OPERATION, UNDO_SQL
2 FROM FLASHBACK_TRANSACTION_QUERY
3 WHERE TABLE_NAME = 'T_FLASH_TRANS';

XID OPERATION UNDO_SQL
---------------- ---------- ------------------------------------------------------------------------
0004001A00000344 INSERT delete from "YANGTK"."T_FLASH_TRANS" where ROWID = 'AAARskAAFAAACY3AAC';
0004001A00000344 UPDATE update "YANGTK"."T_FLASH_TRANS" set "NAME" = 'B' where ROWID = 'AAARskAA
0004001A00000344 UPDATE update "YANGTK"."T_FLASH_TRANS" set "NAME" = 'A' where ROWID = 'AAARskAA
0006002F00000345 INSERT delete from "YANGTK"."T_FLASH_TRANS" where ROWID = 'AAARskAAFAAACY3AAD';
0006002F00000345 UPDATE update "YANGTK"."T_FLASH_TRANS" set "NAME" = 'A1' where ROWID = 'AAARskA
000A005000000343 INSERT delete from "YANGTK"."T_FLASH_TRANS" where ROWID = 'AAARskAAFAAACY3AAB';
000A005000000343 INSERT delete from "YANGTK"."T_FLASH_TRANS" where ROWID = 'AAARskAAFAAACY3AAA';

已选择7行。

下面对第一个更新进行撤销:

SQL> DECLARE
2 V_XID XID_ARRAY;
3 BEGIN
4 V_XID := SYS.XID_ARRAY('0004001A00000344');
5 DBMS_FLASHBACK.TRANSACTION_BACKOUT(1, V_XID);
6 END;
7 /
DECLARE
*
1 行出现错误:
ORA-55504: NOCASCADE
模式下的事务处理冲突

ORA-06512:
"SYS.DBMS_FLASHBACK", line 37
ORA-06512:
"SYS.DBMS_FLASHBACK", line 70
ORA-06512:
line 5

撤销出错,这是由于要撤销第二个事务,这个事务对ID1的记录进行了更新,但是在随后的事务中又对这条记录进行了修改。也就是说这个事务是后面事务的基础,这时没有办法仅仅撤销前面的事务而不影响后面的事务。

对于这种情况,Oracle有三种不同的解决方法,其中最好理解的方法是CASCADE方式:

SQL> DECLARE
2 V_XID XID_ARRAY;
3 BEGIN
4 V_XID := SYS.XID_ARRAY('0004001A00000344');
5 DBMS_FLASHBACK.TRANSACTION_BACKOUT(1, V_XID, DBMS_FLASHBACK.CASCADE);
6 END;
7 /

PL/SQL 过程已成功完成。

SQL> SELECT * FROM YANGTK.T_FLASH_TRANS;

ID NAME
---------- ------------------------------
1 A
2 B

使用CASCADE方式,会根据事务提交的相反顺序,依次撤销所有关联的事务。

在这个例子中,Oracle不但撤销了第一个UPDATE事务,而且撤销了随后的UPDATEINSERT事务。

下面看第二种方式,NONCONFLICT_ONLY。在采用这种方式之前,先要说明一下,TRANSACTION_BACKOUT过程是事务性的,也就是说,如果发现撤销事务后,得到的不是预期的结果,还可以通过ROLLBACK来回滚事务撤销操作本身:

SQL> ROLLBACK;

回退已完成。

SQL> SELECT * FROM YANGTK.T_FLASH_TRANS;

ID NAME
---------- ------------------------------
1 A12
2 B1
3 C
4 D

下面采用NONCONFLICT_ONLY方式进行事务撤销:

SQL> DECLARE
2 V_XID XID_ARRAY;
3 BEGIN
4 V_XID := SYS.XID_ARRAY('0004001A00000344');
5 DBMS_FLASHBACK.TRANSACTION_BACKOUT(1, V_XID, DBMS_FLASHBACK.NONCONFLICT_ONLY);
6 END;
7 /

PL/SQL 过程已成功完成。

SQL> SELECT * FROM YANGTK.T_FLASH_TRANS;

ID NAME
---------- ------------------------------
1 A12
2 B
4 D

对于NONCONFLICT_ONLY方式,Oracle会回滚指定事务中没有被关联的部分。比如这个例子中,UPDATE语句被后面的事务关联,但是INSERT语句并没有被关联。因此,撤销了事务中的INSERT语句,对于UPDATE语句,只有关联的那条数据没有被撤销,而没有被关联的数据则被撤销成功。这种方式可以保证数据库的一致性,但是会损失事务的完整性。

Oracle文档上还描述了一种方式NOCASCADE_FORCE

SQL> ROLLBACK;

回退已完成。

SQL> SELECT * FROM YANGTK.T_FLASH_TRANS;

ID NAME
---------- ------------------------------
1 A12
2 B1
3 C
4 D

SQL> DECLARE
2 V_XID XID_ARRAY;
3 BEGIN
4 V_XID := SYS.XID_ARRAY('0004001A00000344');
5 DBMS_FLASHBACK.TRANSACTION_BACKOUT(1, V_XID, DBMS_FLASHBACK.NOCASCADE_FORCE);
6 END;
7 /

PL/SQL 过程已成功完成。

SQL> SELECT * FROM YANGTK.T_FLASH_TRANS;

ID NAME
---------- ------------------------------
1 A12
2 B
4 D

根据文档上的描述,个人感觉采用这种方式的撤销后,ID1的记录NAME应该为A而不是A12,现在的这种结果与NONCONFLICT_ONLY方式没有差别,怀疑目前的结果是个bug。不过实际如何只能等Oracle推出补丁或者声明bug才能了解。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-69549/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1954
  • 访问量
    10889527