主事务和自治事务的区别?

问题描述 投票:0回答:1

是否有一个 Oracle 接口可以告诉您当前事务是主事务还是具有 PL/SQL 上下文的自治事务?

我知道如何获取当前交易ID:

dbms_transaction.local_transaction_id

这会告诉我是否在交易中。但我需要进一步检查当前事务是否是主事务,或者某些代码是否打开了自治事务。

oracle plsql transactions oracle21c
1个回答
0
投票

我同意贾斯汀的评论。这很可能是一个不应该解决的问题。但是,如果有合理的需要,我会根据要求提供解决方案。

当您启动标记为自治的 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
© www.soinside.com 2019 - 2024. All rights reserved.