【问题标题】:How to get the name of a named transaction in Oracle?如何在 Oracle 中获取命名事务的名称?
【发布时间】:2013-07-17 16:13:48
【问题描述】:

我想在触发器中使用事务的名称,以便将其写入列中。

我试过这个(在 SQL Developer 中):

set transaction name 'hello';
select DBMS_TRANSACTION.LOCAL_TRANSACTION_ID from dual;
commit;

但我得到的不是交易名称,而是某种随机值:

transaction NAME succeeded.
SUBSTR(DBMS_TRANSACTION.LOCAL_TRANSACTION_ID,0,20)
--------------------------------------------------
1.25.19794                                         

committed.

如何获取命名事务的名称?

【问题讨论】:

    标签: oracle plsql transactions


    【解决方案1】:

    我刚刚尝试了类似的方法,对于DBMS_TRANSACTION.LOCAL_TRANSACTION_ID,我得到了9.7.1270 的值。当我按名称查找交易时,我发现了以下内容:

    • v$transaction.XIDUSN = 9
    • v$transaction.XIDSLOT = 7
    • v$transaction.XIDSQN = 1270

    把它们放在一起,你就得到了9.7.1270。因此(请注意,这可能是错误的 - 我发现的文档没有涵盖这一点),您也许能够像这样获得当前的交易名称:

    SELECT Name
    FROM v$transaction
    WHERE xidusn ||'.'|| xidslot ||'.'|| xidsqn = DBMS_TRANSACTION.LOCAL_TRANSACTION_ID;
    

    我可以确定的一个事实:v$transaction 行在您执行以下操作之一之前不会显示:

    1. INSERT/UPDATE/DELETE/MERGE 类型的操作,
    2. 单独调用DBMS_TRANSACTION.LOCAL_TRANSACTION_ID - 这意味着仅在上面的查询中使用它似乎不足以填充v$transaction 行。

    但是,如果我执行上述任一操作,则查询可以正常工作(我现在已经测试了 4 或 5 次),并且由于您将在触发器中尝试它,因此上面的第 2 项应涵盖。

    最后一点:v$transaction 访问受到严格限制,因此大多数用户无法看到它。更复杂的是,v$transaction 不是实际视图;它是视图 sys.v_$transaction 的同义词(请注意美元符号前的下划线),因此这是您在授予时需要使用的名称。而且我很确定您必须以SYSDBA 身份登录才能进行授权-我能够以SYSTEM 用户的身份查询v$transaction,但我没有足够的权限将GRANT SELECT 传递给另一个用户.

    【讨论】:

    • 我怎么能说,访问 v$ 视图是无害的?
    • 认为这是无害的,但我没有令人信服的证据来支持我的立场。我建议在dba.stackexchange.com 上发布问题。包括一个关于你正在尝试做的事情的快速说明,甚至可能是我的查询。那里有一些核心 Oracle 类型可以确认它是否真的有效,并且他们应该能够告诉您授予对视图的访问权限是否是一个好主意。另一种选择:作为 SYSTEM 用户,在 sys.v_$transaction 上创建一个视图(仅在您需要的列上),然后授予用户对该视图的访问权限。我在这里试过了,效果很好。
    • 你告诉保安,“这是 Ed。他是我的经理。他要完成这件事。Ed,这是 Fred - 他是保安。他不会让我做你想做的事. 嘿,当你决定什么是什么时,你们打电话给我,'K?'K。引发一场良好的管理争论总是很有趣——而且在他们做出决定之前,你已经摆脱困境。 :-)
    • 在 18.3 版上,不需要单独调用 DBMS_TRANSACTION.LOCAL_TRANSACTION_ID(在选择列表或 where 条件下对其进行了测试),但我们仍然需要它来“刷新”@ 987654341@ 查看。让文档说v$transaction 在特定情况下可能不会显示每笔交易会很有趣。如果它存在于某个地方。
    【解决方案2】:

    我认为您正在寻找 v$transaction。例如:

    set serveroutput on
    set echo on
    set transaction name 'test1_txn';
    update my_table set dte = sysdate;
    -- this will show the named transaction
    select * from v$transaction where name = 'test1_txn';
    commit;
    -- after commit, won't show
    select * from v$transaction where name = 'test1_txn';
    

    更多详情here

    【讨论】:

    • 如果我尝试访问该视图,我会收到 ORA-00942: table or view does not exist。据我所知,我需要SELECT ANY DICTIONARY。我想我不会得到这个,因为它是系统权限。
    • 它是一个精选的私人,非常无害的 imo。 v$ 视图归 SYS 所有(v$transaction 是 sys.v_$transaction 的公共同义词)。
    • Select 通常不是无害的。选择密码是非常有害的。为什么你认为它是无害的?我认为我无法使用默认用户访问它一定是有原因的。
    • 如果您需要编写需要访问命名参数的触发器或函数,那么在 imo 上要求 v$transaction 上的 select privs 是非常正常的。如果 dbas 或管理层害怕这种选择访问(无论出于何种原因),那么我不确定您应该如何完成这项工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-11
    • 2011-07-30
    • 1970-01-01
    • 2019-08-30
    • 2010-11-28
    • 2017-05-08
    相关资源
    最近更新 更多