在 COMMIT 之前查看不同 SQL Oracle 会话的更改?
See changes of a different SQL Oracle session before COMMIT?
我协调了 Oracle PL/SQL DML 脚本的实施,但要在生产中执行此操作,我通常会联系 DBA 团队让他们运行 脚本,前提是他们有适当的权限。
有没有办法让我的用户在实际提交之前看到更改?我知道这些更改将在执行脚本的会话中生效,但是有没有办法让不同的会话以及不同的用户看到它们?
在提交更改之前,一个会话无法看到另一个会话所做的更改。
不,这是不可能的,这是设计使然。根据定义,RDBMS 的 ACID 属性包括“隔离”,它可以防止各个连接相互感知,即看到另一个会话中的更改。
无法在另一个会话中查看一个会话未提交的更改。
但是,由于您是 运行 一个 PL/SQL DML 脚本,您可以尝试在脚本中登录以查看脚本进度。
您需要使用单独的 PL/SQL 块和 AUTONOMOUS 事务来记录数据。
包 DBMS_XA can transfer an uncommitted transaction from one session to another. The second session can view the uncommitted data and can commit, rollback, or pass the transaction on again. The below example is based on this oracle-base article,虽然它对我有用,但我以前从未在生产中使用过此功能,可能存在我不知道的复杂情况。
首先,创建一个table例子使用的:
--DROP TABLE tab1;
CREATE TABLE tab1 (
id NUMBER
);
第 1 节
将事务超时从 60 秒更改为更大的值:
DECLARE
l_return PLS_INTEGER;
BEGIN
l_return := SYS.DBMS_XA.xa_settimeout(500);
END;
/
开始交易,传入一个幻数来命名交易(999):
DECLARE
l_xid DBMS_XA_XID := DBMS_XA_XID(999);
l_return PLS_INTEGER;
BEGIN
l_return := SYS.DBMS_XA.xa_start(xid => l_xid,
flag => DBMS_XA.TMNOFLAGS);
END;
/
在这里做真正的工作,无需提交:
INSERT INTO tab1 (id) VALUES (1);
结束事务以便稍后可以附加另一个会话:
DECLARE
l_xid DBMS_XA_XID := DBMS_XA_XID(999);
l_return PLS_INTEGER;
BEGIN
l_return := SYS.DBMS_XA.xa_end(xid => l_xid,
flag => DBMS_XA.TMSUSPEND);
END;
/
数据已从我们的会话中消失 - 此 table 不包括我们刚刚插入的行。另一个会话将需要附加到全局事务并提交或回滚它。
select * from tab1;
第 2 节
最初,此会话无法看到数据:
select * from tab1;
附加到全局事务,使用相同的幻数 (999):
DECLARE
l_xid DBMS_XA_XID := DBMS_XA_XID(999);
l_return PLS_INTEGER;
BEGIN
l_return := SYS.DBMS_XA.xa_start(xid => l_xid,
flag => DBMS_XA.TMRESUME);
END;
/
现在只有这个会话可以看到新行:
select * from tab1;
第二个会话可以提交、回滚或将事务传递给另一个会话。要通过交易,请再次调用 DBMS_XA.XA_END
并进行另一个会话,然后调用 DBMS_XA.XA_START
.
我协调了 Oracle PL/SQL DML 脚本的实施,但要在生产中执行此操作,我通常会联系 DBA 团队让他们运行 脚本,前提是他们有适当的权限。
有没有办法让我的用户在实际提交之前看到更改?我知道这些更改将在执行脚本的会话中生效,但是有没有办法让不同的会话以及不同的用户看到它们?
在提交更改之前,一个会话无法看到另一个会话所做的更改。
不,这是不可能的,这是设计使然。根据定义,RDBMS 的 ACID 属性包括“隔离”,它可以防止各个连接相互感知,即看到另一个会话中的更改。
无法在另一个会话中查看一个会话未提交的更改。 但是,由于您是 运行 一个 PL/SQL DML 脚本,您可以尝试在脚本中登录以查看脚本进度。 您需要使用单独的 PL/SQL 块和 AUTONOMOUS 事务来记录数据。
包 DBMS_XA can transfer an uncommitted transaction from one session to another. The second session can view the uncommitted data and can commit, rollback, or pass the transaction on again. The below example is based on this oracle-base article,虽然它对我有用,但我以前从未在生产中使用过此功能,可能存在我不知道的复杂情况。
首先,创建一个table例子使用的:
--DROP TABLE tab1;
CREATE TABLE tab1 (
id NUMBER
);
第 1 节
将事务超时从 60 秒更改为更大的值:
DECLARE
l_return PLS_INTEGER;
BEGIN
l_return := SYS.DBMS_XA.xa_settimeout(500);
END;
/
开始交易,传入一个幻数来命名交易(999):
DECLARE
l_xid DBMS_XA_XID := DBMS_XA_XID(999);
l_return PLS_INTEGER;
BEGIN
l_return := SYS.DBMS_XA.xa_start(xid => l_xid,
flag => DBMS_XA.TMNOFLAGS);
END;
/
在这里做真正的工作,无需提交:
INSERT INTO tab1 (id) VALUES (1);
结束事务以便稍后可以附加另一个会话:
DECLARE
l_xid DBMS_XA_XID := DBMS_XA_XID(999);
l_return PLS_INTEGER;
BEGIN
l_return := SYS.DBMS_XA.xa_end(xid => l_xid,
flag => DBMS_XA.TMSUSPEND);
END;
/
数据已从我们的会话中消失 - 此 table 不包括我们刚刚插入的行。另一个会话将需要附加到全局事务并提交或回滚它。
select * from tab1;
第 2 节
最初,此会话无法看到数据:
select * from tab1;
附加到全局事务,使用相同的幻数 (999):
DECLARE
l_xid DBMS_XA_XID := DBMS_XA_XID(999);
l_return PLS_INTEGER;
BEGIN
l_return := SYS.DBMS_XA.xa_start(xid => l_xid,
flag => DBMS_XA.TMRESUME);
END;
/
现在只有这个会话可以看到新行:
select * from tab1;
第二个会话可以提交、回滚或将事务传递给另一个会话。要通过交易,请再次调用 DBMS_XA.XA_END
并进行另一个会话,然后调用 DBMS_XA.XA_START
.