ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Flashback Transaction Backout

Flashback Transaction Backout

原创 Linux操作系统 作者:guoge 时间:2008-12-30 15:37:34 0 删除 编辑
Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 我们在进行开发的时候,常面临这样一个问题:例如假设我在调试一个门诊药局发药的程序,当我对某个处方发药确认时,会出现错误。由于处方确认后,这条处方记录会从表里删除。为了在调试中不停地模拟这个错误,可以有两种方法:1、重新模拟生成该处方。由于流程限制,因此必须挂号、医生站、门诊收费等前期模块都走一遍,生成该待发药处方。2、对处方确认进行反操作,例如处方确认包括三方面操作:删除待发药处方、减库存、药品处方插入一条记录。那么反操作包括:将药品处方生成的记录删除、恢复原来库存数、同样插入一条待发药处方。如果恰巧某个操作可能触发触发器生成其它操作,那反操作可能还有其它。这两种方法都比较麻烦,费时费力。

ORACLE10G下使用Flashback Database,将数据库恢复到处方发药前的某一时间,这种方法对于当前只有你一个人在操作数据库是比较有用。如果恰好有其他人员也在使用这个数据库,小心了。

ORACLE11G中对 Flashback 引进了Flashback Transaction Backout ,也就是对事务进行Flashback

使用这个特性,要求数据库处于归档模式,并且“add supplemental log data”例如:

startup mount;

 

alter database archivelog;

alter database open;

alter system archive log current;

alter database add supplemental log data;

 

 

假设有两个表t1 ,t2 ,并有触发器如下:

CREATE TABLE t1 (testcol VARCHAR2(3));

 

CREATE TABLE t2 (testcol VARCHAR2(3));

 

CREATE OR REPLACE TRIGGER row_level

BEFORE INSERT

ON t1

FOR EACH ROW

BEGIN

  INSERT INTO t2

  VALUES

  (:NEW.testcol);

END row_level;

/

也就是说没插入一条t1记录,在t2中也插入一条记录。

执行如下操作填充数据:

BEGIN

  INSERT INTO t1 VALUES ('ABC');

  INSERT INTO t1 VALUES ('DEF');

  COMMIT;

  dbms_lock.sleep(50);

  INSERT INTO t1 VALUES ('GHI');

  INSERT INTO t1 VALUES ('JKL');

  COMMIT;

  dbms_lock.sleep(50);

  INSERT INTO t1 VALUES ('MNO');

  COMMIT;

  dbms_lock.sleep(50);

END;

/

 

执行结束后,我们看看

SELECT versions_xid, versions_startscn, versions_endscn, versions_operation, testcol

FROM t1

VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE;

 

VERSIONS_XID     VERSIONS_STARTSCN VERSIONS_ENDSCN V TES

---------------- ----------------- --------------- - ---

08001400CB020000           1145327                 I MNO

0600140045020000           1145294                 I JKL

0600140045020000           1145294                 I GHI

03000F005C020000           1145249                 I DEF

03000F005C020000           1145249                 I ABC

 

 

SELECT versions_xid, versions_startscn, versions_endscn, versions_operation, testcol

FROM t2

VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE;

VERSIONS_XID     VERSIONS_STARTSCN VERSIONS_ENDSCN V TES

---------------- ----------------- --------------- - ---

08001400CB020000           1145327                 I MNO

0600140045020000           1145294                 I JKL

0600140045020000           1145294                 I GHI

                                                     ABC

                                                     DEF

 

我对表t2 ”GHI’ 进行如下操作:

SQL> delete from t2 where testcol='GHI';

 

1 row deleted.

 

SQL> insert into t2 values ('PQR') ;

 

1 row created.

 

SQL> commit ;

 

Commit complete.

 

SQL> select * from t2 ;

 

TES

---

ABC

DEF

JKL

MNO

PQR

 

5 rows selected.

 

这个时候,我想回退将’GHI’’JKL’插入到表t1的事务,如果成功的话,应该t2 也没有’GHI’’JKL’ ,而且t2也应该没有’PQR’,因为插入’PQR’的操作是依赖于‘GHI’ 的存在。

 我们看到插入’GHI’’JKL’的事务的VERSIONS_XID0600140045020000 ,因此执行:

SQL> DECLARE

 xa sys.xid_array := sys.xid_array();

BEGIN

  xa.extend;

  dbms_output.put_line(xa.last);

  xa(1) := '0600140045020000';

  dbms_flashback.transaction_backout(1, xa , dbms_flashback.CASCADE);

END;

/ 

PL/SQL procedure successfully completed.

再查询一下:

SQL> select * from t1 ;

 

TES

---

ABC

DEF

MNO

 

3 rows selected.

 

SQL> select * from t2 ;

 

TES

---

ABC

DEF

MNO

 

一切正常。

Flashback使用的是UNDO的内容,如果时间过长,UNDO里没有需要的信息,可能需要使用Logmnr挖掘日志。 可以参考Oracle Database 11g: Flashback Transaction Backout (http://www.databasejournal.com/features/oracle/article.php/3792961/Oracle-Database-11g-Flashback-Transaction-Backout.htm).

另外也可以参考  11g FLASHBACK Compensating Transaction(http://www.dba-oracle.com/t_11g_new_flashback_compensating.htm)

本文的例子来自于Oracle DBMS_FLASHBACK(http://www.psoug.org/reference/dbms_flashback.html)

 

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

上一篇: ORACLE 压缩
请登录后发表评论 登录
全部评论

注册时间:2007-12-12

  • 博文量
    72
  • 访问量
    226226