Oracle11新特性——撤銷事務(二)
打算寫一系列的文章介紹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
撤銷出錯,這是由於要撤銷第二個事務,這個事務對ID為1的記錄進行了更新,但是在隨後的事務中又對這條記錄進行了修改。也就是說這個事務是後面事務的基礎,這時沒有辦法僅僅撤銷前面的事務而不影響後面的事務。
對於這種情況,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事務,而且撤銷了隨後的UPDATE和INSERT事務。
下面看第二種方式,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
根據文件上的描述,個人感覺採用這種方式的撤銷後,ID為1的記錄NAME應該為A而不是A12,現在的這種結果與NONCONFLICT_ONLY方式沒有差別,懷疑目前的結果是個bug。不過實際如何只能等Oracle推出補丁或者宣告bug才能瞭解。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-69549/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle11新特性——撤銷事務(一)Oracle
- Oracle11新特性——撤銷事務(三)Oracle
- Oracle11新特性——PLSQL新特性(二)OracleSQL
- Oracle11新特性——虛擬列(二)Oracle
- Oracle11新特性——PLSQL新特性(七)OracleSQL
- Oracle11新特性——PLSQL新特性(六)OracleSQL
- Oracle11新特性——PLSQL新特性(五)OracleSQL
- Oracle11新特性——PLSQL新特性(四)OracleSQL
- Oracle11新特性——PLSQL新特性(三)OracleSQL
- Oracle11新特性——PLSQL新特性(一)OracleSQL
- Oracle11新特性——行列轉換語句(二)Oracle
- Oracle11新特性——分割槽功能增強(二)Oracle
- Oracle11新特性——備份恢復功能增強(二)Oracle
- Oracle11新特性——線上操作功能增強(二)Oracle
- Oracle11新特性——PLSQL函式快取結果(二)OracleSQL函式快取
- Oracle11新特性——虛擬列Oracle
- git進階(撤銷pull、撤銷merge、撤銷add)Git
- Oracle11新特性——分割槽功能增強Oracle
- 網頁撤銷後ubuntu本地撤銷網頁Ubuntu
- Oracle11新特性——分割槽功能增強(五)Oracle
- Oracle11新特性——分割槽功能增強(四)Oracle
- Oracle11新特性——行列轉換語句(一)Oracle
- Oracle11新特性——分割槽功能增強(三)Oracle
- Oracle11新特性——分割槽功能增強(一)Oracle
- 認識 MongoDB 4.0 的新特性——事務(Transactions)MongoDB
- 什麼是事務、事務特性、事務隔離級別、spring事務傳播特性?Spring
- Oracle11新特性——備份恢復功能增強Oracle
- Oracle11新特性——SQL快取結果集(五)OracleSQL快取
- Oracle11新特性——SQL快取結果集(三)OracleSQL快取
- ❤️🔥 Solon Cloud Event 新的事務特性與應用Cloud
- git撤銷命令Git
- Oracle11新特性——備份恢復功能增強(六)Oracle
- Oracle11新特性——備份恢復功能增強(五)Oracle
- Oracle11新特性——備份恢復功能增強(四)Oracle
- Oracle11新特性——備份恢復功能增強(三)Oracle
- Oracle11新特性——備份恢復功能增強(一)Oracle
- Oracle11新特性——備份恢復功能增強(十)Oracle
- Oracle11新特性——備份恢復功能增強(九)Oracle