Oracle11新特性——撤銷事務(二)

yangtingkun發表於2007-12-18

打算寫一系列的文章介紹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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章