Откат в процедуре, вызванной через dblink - PullRequest
0 голосов
/ 22 марта 2019

У меня странная ситуация

Это немного сложно объяснить, но я сделаю все возможное

Включено 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 голосов
/ 22 марта 2019

Проблема в том, что вы «обработали» исключение в [function 2]. Вы не должны помещать блок исключений в [function 2] вообще. И пусть исключение распространяется до [процедура 1]. Здесь вы будете явно или явно откат.

Если у вас должен быть блок исключений в [function 2], у вас должен быть [повышение] в конце. Обрабатывая подобное исключение, вы говорите: «Я обработал это, и для всех практических целей вызывающий объект не должен думать, что что-то плохое случилось]

0 голосов
/ 22 марта 2019

Вы должны иметь коммит где-то в своем коде либо перед исключением повышения, либо в процедуре3 . Я только что протестировал приведенный ниже код, и он откатил все до исключения. Пожалуйста, игнорируйте соглашения об именах, пришлось идти из-за нехватки времени.

База данных 3 CREATE TABLE temp (col1 NUMBER);

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

database2

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

Database1

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

x возвращает 0 из-за исключения в функции DB2.

А ниже приведены данные, когда я выполнил приведенный ниже оператор на DB3

select * from temp;

enter image description here

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...