这是场景, 我正在编写一个对多个表执行DML(插入,删除)操作的过程。如果出现异常,我需要从大多数表中回滚数据,除了一个。
示例:
步骤{
1 Insert into table1
2 Delete from table2
3 Insert into Table3
4 Insert into table4
Commit;
异常
Rollback;
}
如果第4次插入中有任何异常,我需要回滚除第3次以外的所有先前交易。 我知道,提交/回滚并不是那样的。但是在创建table3时可能有办法,我可以设置一些参数,以便table3上的每个INSERT语句都自动提交。
答案 0 :(得分:3)
可以使用自主交易。
CREATE TABLE t1 (x INTEGER PRIMARY KEY);
CREATE TABLE t2 (x INTEGER);
CREATE TABLE t3 (x INTEGER);
CREATE TABLE t4 (x INTEGER REFERENCES t1(x));
然后运行这个匿名PL / SQL。仔细观察,当声明它时,本地过程upd_table_3
不会运行。它在主BEGIN
块中调用时运行:
DECLARE
PROCEDURE upd_table_3 IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO t3 VALUES (3);
COMMIT;
END;
BEGIN
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2);
upd_table_3;
INSERT INTO t4 VALUES (4);
COMMIT;
END;
/
使用ORA-02291
在第4个插页上故意失败该程序。我是这样做的。然后
ROLLBACK;
除了t3
之外,所有表都应该回滚,我们在自治事务中进行了插入。
SELECT * FROM t1;
no rows selected
SELECT * FROM t2;
no rows selected
SELECT * FROM t3;
X
----------
3
SELECT * FROM t4;
no rows selected
答案 1 :(得分:2)
从你的帖子解释我理解的是#3 insert不依赖于其他插入,你无论如何想要提交它。在这种情况下,您可以将它们放在不同的事务块中,例如。
begin transaction
1 Insert into table1
2 Delete from table2
4 Insert into table4
Commit;
Exception
Rollback;
第二部分
begin transaction
3 Insert into Table3
commit
On Exception
Rollback;
(OR)使用下面的save point
,这样#3插入就不会被回滚。
BEGIN
SAVEPOINT startpoint;
3 Insert into Table3;
SAVEPOINT startpoint2;
1 Insert into table1;
2 Delete from table2;
4 Insert into table4;
EXCEPTION
WHEN SOMETHING THEN
ROLLBACK TO startpoint2;
RAISE;
END;
PS:语法可能不合适;所以请查阅文档。 SAVEPOINT
来自BEGIN - END block atomic transactions in PL/SQL
答案 2 :(得分:0)
无所事事。拿你的剧本:
1 Insert into table1
2 Delete from table2
3 Insert into Table3
4 Insert into table4
Commit;
假设你在语句4中得到一个异常,那么语句4实际上没有执行,因此回滚语句4是没有意义的。在这种情况下,一个简单的COMMIT
只提交语句1,2,3。
但是,例如,当您在语句3处获得异常时,它看起来会有所不同(而语句4运行正常)。在这种情况下,您是否愿意回滚到语句2,即回滚声明4?然后你必须使用其他答案中提到的SAVEPOINTS
。