Create oracle table with auto commit on

a 夏天 提交于 2019-12-12 14:48:09

问题


Here is the scenario, I am writing a procedure which performs DML(insert,delete) operations on multiple tables. In case of exception I need to rollback data from most of the tables except one.

Example:

Procedure{

1 Insert into table1

2 Delete from table2

3 Insert into Table3

4 Insert into table4

 Commit;

Exception

Rollback;

}

If there is any exception in 4th Insert, I need to rollback all previous transaction except 3rd one. I know, commit/rollback doesn't work like that. But maybe is there way while creating table3, I can set some parameter so that every INSERT statement on table3 will be auto commited.


回答1:


It's possible using an Autonomous Transaction.

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));

Then run this anononymous PL/SQL. Look carefully, the local procedure upd_table_3 isn't run when it's declared. It's run when called within the main BEGIN block:

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;
/

The procedure should fail intentionally on the 4th insert with ORA-02291. I made it this way. Then

ROLLBACK;

All the tables should be rolled back except t3, which we did the insert in an autonomous transaction.

SELECT * FROM t1;

no rows selected

SELECT * FROM t2;

no rows selected

SELECT * FROM t3;

         X
----------
         3

SELECT * FROM t4;

no rows selected



回答2:


From your post explanation what I understood is #3 insert has no dependency on other insert and you anyways want to commit it. In that case you can have them in different transaction block like.

begin transaction
1 Insert into table1

2 Delete from table2

4 Insert into table4

Commit;

Exception

Rollback;

Second Part

begin transaction
3 Insert into Table3
commit

On Exception 
Rollback;

(OR) using a save point like below, that way #3 insert will not be rolled back.

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: Syntax may not be proper; So consult the documentation. SAVEPOINT idea taken from BEGIN - END block atomic transactions in PL/SQL




回答3:


There is nothing to do. Take your script:

1 Insert into table1

2 Delete from table2

3 Insert into Table3

4 Insert into table4

Commit;

Assume you get an exception in statement 4, then statement 4 is actually not executed thus it does not make sense to rollback statement 4. A simple COMMIT will commit only statements 1,2,3 in this case.

However, it looks different when you get an exception at statement 3, for example (while statement 4 runs fine). Do you like to rollback to statement 2 in this case, i.e. rollback also statement 4? Then you have to work with SAVEPOINTS as mentioned in the other answers.



来源:https://stackoverflow.com/questions/24419183/create-oracle-table-with-auto-commit-on

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!