Можно ли увидеть изменения в другой сессии до COMMIT в ней?

Я реализовал PL/SQL скрипт. В продуктивной среде скрипт запустит DBA.

Есть ли способ, увидеть изменения, которые произвёл скрипт, до того, как будет выполнен COMMIT?

Знаю, что изменения будут активны в той сессии, в которой выполнялся скрипт. Но может есть способ в другой сессии, или более того, с другим пользователем, увидеть эти изменения?


Свободный перевод вопроса See changes of a different SQL Oracle session before COMMIT? от участника @Felipe Vidal Otero


Ответы (1 шт):

Автор решения: 0xdb

Пакет DBMS_XA может передавать незафиксированную транзакцию из одной сессии в другой. Другая сессия может просматривать незафиксированные данные, может фиксировать, откатывать или снова передать их в другую транзакцию. Приведенный ниже пример основан на этой статье ORACLE-BASE и выглядит, что работает, но никогда не проверял в продуктивной среде, поэтому - на свой страх и риск.

Сессия 1

Тестовая таблица и изменение тайм-аута на ветвление транзакций (по умочанию 60 сек.):

create table t1 (id number);

var ret number
exec :ret := dbms_xa.xa_settimeout(600);

Начните транзакцию с магическим числом транзакции (9999) и вставте первую запись:

exec :ret := sys.dbms_xa.xa_start (xid=>dbms_xa_xid (9999), flag=>dbms_xa.tmnoflags);

insert into t1 (id) values (1);

Завершим транзакцию, чтобы к ней можно было подключить другую сессию. Запись, которая была только что вставлена, будет больше не доступна в это сессии:

exec :ret := sys.dbms_xa.xa_end (xid=>dbms_xa_xid (9999), flag=>dbms_xa.tmsuspend);

select * from t1;

no rows selected

Сессия 2

Изначально, эта сессия не может видеть данные:

select * from t1;

no rows selected

Подключиться к глобальной транзакции, используя то же самое магическое число (9999). Затем, только эта сессия может видеть новую запись. В залючение, эта сессия должна зафиксировать, откатить, или опять - отсоединится от транзакции:

var ret number
exec :ret := dbms_xa.xa_start (xid=>dbms_xa_xid (9999), flag=>dbms_xa.tmresume);

select * from t1
/

        ID
----------
         1

begin 
    :ret := dbms_xa.xa_end (xid=>dbms_xa_xid (9999), flag=>dbms_xa.tmsuccess);
    if :ret = dbms_xa.xa_ok then 
        :ret := dbms_xa.xa_commit (xid=>dbms_xa_xid (9999), onePhase=>true);
    end if;
end;
/

Свободный перевод ответа от участника @Jon Heller

→ Ссылка