ITPub博客

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

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

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

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

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

这一篇介绍撤销事务与外键约束的关系。

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

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


上面一篇文章简单介绍了撤销事务的几种选项,这几种选项是对关联事务而言的,对于事务之前的主外键约束,结果又是不同的。

先建立测试环境:

SQL> CREATE TABLE T_PRIMARY (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30));

表已创建。

SQL> CREATE TABLE T_FOREIGN (FID NUMBER, FOREIGN KEY (FID) REFERENCES T_PRIMARY);

表已创建。

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

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> UPDATE T_PRIMARY SET NAME = 'A1';

已更新 1 行。

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

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> INSERT INTO T_FOREIGN VALUES (2);

已创建 1 行。

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

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> CONN SYS/test@172.0.2.61/TEST11G.NETDB AS SYSDBA已连接。
SQL> COL OPERATION FORMAT A10
SQL> COL UNDO_SQL FORMAT A85
SQL> SET LINES 120 PAGES 100
SQL> SELECT XID, OPERATION, UNDO_SQL
2 FROM FLASHBACK_TRANSACTION_QUERY
3 WHERE TABLE_NAME = 'T_PRIMARY';

XID OPERATION UNDO_SQL
---------------- ---------- ------------------------------------------------------------------------
000500590000035B INSERT delete from "YANGTK"."T_PRIMARY" where ROWID = 'AAARuLAAFAAACY9AAB';
000500590000035B UPDATE update "YANGTK"."T_PRIMARY" set "NAME" = 'A' where ROWID = 'AAARuLAAFAAA
0009000500000363 INSERT delete from "YANGTK"."T_PRIMARY" where ROWID = 'AAARuLAAFAAACY9AAC';
000A00680000037C INSERT delete from "YANGTK"."T_PRIMARY" where ROWID = 'AAARuLAAFAAACY9AAA';

下面开始进行撤销测试:

SQL> DECLARE
2 V_XID XID_ARRAY;
3 BEGIN
4 V_XID := SYS.XID_ARRAY('000500590000035B');
5 DBMS_FLASHBACK.TRANSACTION_BACKOUT(1, V_XID);
6 END;
7 /
DECLARE
*
1 行出现错误:
ORA-55511:
闪回事务处理在执行还原 SQL 时出错

ORA-02292:
违反完整约束条件 (ORA-02292: 违反完整约束条件 (YANGTK.SYS_C0011048) - 已找到子记录
.) -
已找到子记录
ORA-06512:
"SYS.DBMS_FLASHBACK", line 37
ORA-06512:
"SYS.DBMS_FLASHBACK", line 70
ORA-06512:
line 5

由于要撤销的事务中包括对主表记录的插入,而这条记录被子表引用,因此撤销肯定会出现错误。尝试使用CASCADE方式进行撤销:

SQL> DECLARE
2 V_XID XID_ARRAY;
3 BEGIN
4 V_XID := SYS.XID_ARRAY('000500590000035B');
5 DBMS_FLASHBACK.TRANSACTION_BACKOUT(1, V_XID, DBMS_FLASHBACK.CASCADE);
6 END;
7 /
DECLARE
*
1 行出现错误:
ORA-55511:
闪回事务处理在执行还原 SQL 时出错

ORA-02292:
违反完整约束条件 (ORA-02292: 违反完整约束条件 (YANGTK.SYS_C0011048) - 已找到子记录
.) -
已找到子记录
ORA-06512:
"SYS.DBMS_FLASHBACK", line 37
ORA-06512:
"SYS.DBMS_FLASHBACK", line 70
ORA-06512:
line 5

CASCADE方式只对关联事务有效,而对这种主外键关系无效,因此,如果撤销事务操作会违反主外键约束,那么即使使用CASCADE方式也没有作用。

同样的,另外两种方式NONCONFLICT_ONLYNOCASCADE_FORCE也没有作用:

SQL> DECLARE
2 V_XID XID_ARRAY;
3 BEGIN
4 V_XID := SYS.XID_ARRAY('000500590000035B');
5 DBMS_FLASHBACK.TRANSACTION_BACKOUT(1, V_XID, DBMS_FLASHBACK.NONCONFLICT_ONLY);
6 END;
7 /
DECLARE
*
1 行出现错误:
ORA-55511:
闪回事务处理在执行还原 SQL 时出错

ORA-02292:
违反完整约束条件 (ORA-02292: 违反完整约束条件 (YANGTK.SYS_C0011048) - 已找到子记录
.) -
已找到子记录
ORA-06512:
"SYS.DBMS_FLASHBACK", line 37
ORA-06512:
"SYS.DBMS_FLASHBACK", line 70
ORA-06512:
line 5


SQL> DECLARE
2 V_XID XID_ARRAY;
3 BEGIN
4 V_XID := SYS.XID_ARRAY('000500590000035B');
5 DBMS_FLASHBACK.TRANSACTION_BACKOUT(1, V_XID, DBMS_FLASHBACK.NOCASCADE_FORCE);
6 END;
7 /
DECLARE
*
1 行出现错误:
ORA-55511:
闪回事务处理在执行还原 SQL 时出错

ORA-02292:
违反完整约束条件 (ORA-02292: 违反完整约束条件 (YANGTK.SYS_C0011048) - 已找到子记录
.) -
已找到子记录
ORA-06512:
"SYS.DBMS_FLASHBACK", line 37
ORA-06512:
"SYS.DBMS_FLASHBACK", line 70
ORA-06512:
line 5

唯一的方法是包括参考主键信息的外键事务一起进行撤销:

SQL> DECLARE
2 V_XID XID_ARRAY;
3 BEGIN
4 V_XID := SYS.XID_ARRAY('0009000500000363', '000500590000035B');
5 DBMS_FLASHBACK.TRANSACTION_BACKOUT(2, V_XID);
6 END;
7 /

PL/SQL 过程已成功完成。

SQL> SELECT * FROM YANGTK.T_PRIMARY;

ID NAME
---------- ------------------------------
1 A

感觉这一点上撤销事务的实现有点问题,主外键约束事务的撤销应该可以仿效关联事务的方式实现。否则撤销事务在实际工作中就会很难使用。

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

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

注册时间:2007-12-29

  • 博文量
    1954
  • 访问量
    10888210