在通过dblink调用的过程中进行回滚

时间:2019-03-21 22:57:45

标签: sql oracle plsql

我的情况很奇怪

很难解释,但我会尽力的

包括3个不同的数据库

我从DB1调用DB2上的函数(通过dblink)

该过程调用另一个将数据插入DB3上的表的过程

DB2上的函数具有EXCEPTION句柄,该句柄应在发生异常的情况下回滚它所做的一切

我确实运行了示例,并且一切顺利(没有错误),但是没有回退过程3中的插入,因此我必须从DB1回滚到真正的回滚

如果我从db1中提交,则会插入行

我做错什么了吗,有没有办法直接从db2上的函数回滚

这是一些示例代码:

--DB1
PROCEDURE 1
BEGIN
    x := function2@dblink_to_db2();
END;

--DB2
FUNCTION 2
BEGIN
    procedure3();
    RAISE SOME EXCEPTION;
EXCEPTION
    WHEN OTHERS THEN
        ROLLBACK;
        do_something_else();
        RETURN 0;
END;

PROCEDURE 3
BEGIN
    INSERT INTO tableA@dblink_to_db3 VALUES ... ;
END;

因此不会引发任何错误,但是不会回滚到db3上的表中

2 个答案:

答案 0 :(得分:0)

您必须在引发异常之前或在Procedure3中在代码中的某个位置进行提交。我只是测试了下面的代码,它回滚了异常之前的所有内容。请忽略命名约定,由于时间限制而不得不使用。

数据库3     创建表温度     (col1 NUMBER);

create or replace procedure testp(i number)
as
BEGIN
    INSERT INTO temp VALUES (i);
END;
/

数据库2

CREATE OR REPLACE FUNCTION DLR_TRANS.testf(i number)
return number
as
e exception;
BEGIN
    testp@TO_DB3(i);
    RAISE e;
EXCEPTION
    WHEN OTHERS THEN
        ROLLBACK;
        RETURN 0;
END;
/

数据库1

declare
x number;
BEGIN
    x := testf@TO_DB2(15);
    DBMS_OUTPUT.PUT_LINE ( 'x = ' || x );
    commit;
END;

由于DB2函数异常,x返回0。

下面是我在DB3上运行以下语句时的数据

select * from temp;

enter image description here

希望这会有所帮助

答案 1 :(得分:0)

问题在于您已“处理” [功能2]中的异常。您完全不应将异常块放在[功能2]中。并让异常传播到[过程1]。在这里,您将隐式或显式回滚。

如果在[功能2]中必须有一个异常块,那么末尾应该有[筹集]。处理这样的异常是说[我已处理,并且出于所有实际目的,调用方不应认为已发生任何不良情况