是否有一个 Oracle 接口可以告诉您当前事务是主事务还是具有 PL/SQL 上下文的自治事务?
我知道如何获取当前交易ID:
dbms_transaction.local_transaction_id
这会告诉我是否在交易中。但我需要进一步检查当前事务是否是主事务,或者某些代码是否打开了自治事务。
我同意贾斯汀的评论。这很可能是一个不应该解决的问题。但是,如果有合理的需要,我会根据要求提供解决方案。
当您启动标记为自治的 PL/SQL 块时,当前事务指针 (
v$session.taddr
) 将为 NULL,即使当前事务仍然存在并且仍可在 v$transaction
中找到。当您在该自治事务层中执行第一个 DML 操作时,您现在在 v$transaction
中有 two事务条目,但您的事务指针 (
v$session.taddr
) 仅指向最后一个/当前条目。这是有道理的,因为每个会话只有一行的 v$session
只能为您提供该行的一个交易地址,而您实际上有两个。
幸运的是,
taddr/addr
并不是这些视图之间的唯一联系。你也有 ses_addr/saddr
走另一条路。因此,您可以使用它来测试您是否拥有另一笔交易,但该交易不是您的会话所指向的交易:
DECLARE
FUNCTION i_am_autonomous
RETURN varchar2
AS
var_exists integer;
BEGIN
SELECT COUNT(*)
INTO var_exists
FROM v$transaction t,
v$session s
WHERE t.ses_addr = s.saddr
AND s.sid = SYS_CONTEXT('USERENV','SID')
AND (s.taddr IS NULL OR s.taddr <> t.addr);
IF var_exists = 0
THEN
RETURN 'N';
ELSE
RETURN 'Y';
END IF;
END i_am_autonomous;
PROCEDURE ptest
AS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
dbms_output.put_line('inside autonomous but before inner transaction start:'||i_am_autonomous);
INSERT INTO tmp1 VALUES (2);
dbms_output.put_line('after inner transaction:'||i_am_autonomous);
ROLLBACK;
END ptest;
BEGIN
INSERT INTO tmp1 VALUES (1);
dbms_output.put_line('outer transaction:'||i_am_autonomous);
ptest;
ROLLBACK;
END;
输出:
outer transaction:N
inside autonomous but before inner transaction start:Y
after inner transaction:Y