如何使用JDBC或Hibernate获取当前数据库事务ID?

7
我在谷歌上搜寻了很久,但都没有找到相关的内容。我想要获得长时间运行的事务。目前,我通过查看information_schema.INNODB_TRX 或者使用show engine innodb status命令来获取trx_id, 然后打开general_logs来查看运行的所有查询语句。
是否有一种方法,可以使用jdbchibernate在我的代码中获取此transaction_id,以便我可以将其记录在我的服务器日志中?
1个回答

8

Oracle

在使用Oracle时,您需要执行以下SQL查询:

SELECT RAWTOHEX(tx.xid)
FROM v$transaction tx
JOIN v$session s ON tx.ses_addr = s.saddr
v$transaction视图提供有关当前运行的数据库事务的信息。但是,在我们的系统中可能有多个正在运行的事务,因此我们将v$transactionv$session视图连接起来。 v$session视图提供有关当前会话或数据库连接的信息。通过在v$transactionv$session视图之间匹配会话地址,我们可以找到由v$transaction视图中的xid列给出的当前正在运行的事务标识符。
由于xid列的类型为RAW,因此我们使用RAWTOHEX将事务标识符二进制值转换为其十六进制表示形式。

只有当Oracle需要分配撤消段时才分配事务标识符,这意味着已执行INSERT、UPDATE或DELETE DML语句。

因此,只读事务不会被分配事务标识符。

SQL Server

在使用SQL Server时,只需执行以下SQL查询:

SELECT CONVERT(VARCHAR, CURRENT_TRANSACTION_ID())

因为函数返回一个列值,我们使用将其转换为字符串表示形式。

PostgreSQL

当使用PostgreSQL服务器时,您可以执行以下SQL查询以获取当前事务ID:
SELECT CAST(txid_current() AS text)

由于txid_current函数返回一个BIGINT列值,我们使用CAST来获取其字符串表示。

MySQL和MariaDB

当使用MySQL或MariaDB时,您可以执行以下SQL查询以获取当前事务ID:

SELECT tx.trx_id
FROM information_schema.innodb_trx tx
WHERE tx.trx_mysql_thread_id = connection_id()

information_schema目录中的innodb_trx视图提供了当前运行的数据库事务的信息。由于在我们的系统中可能有多个事务正在运行,因此我们需要通过匹配会话或数据库连接标识符与当前运行的会话来过滤事务行。
与Oracle一样,自MySQL 5.6以来,仅读写事务将获得事务标识符。由于分配事务ID具有一定的开销,只读事务跳过此过程。有关更多详细信息,请查看这篇文章
MariaDB中的只读事务优化方式与此相同,即仅为读写事务分配事务ID。
使用HyperSQL数据库时,可以执行以下SQL查询以获取当前事务ID:
VALUES (TRANSACTION_ID())

使用MDC记录事务ID

事务ID对于日志记录非常有用,因为它允许我们聚合在给定数据库事务上下文中执行的所有操作。

假设我们已经将上述SQL查询封装在一个名为transactionId的方法中,我们可以提取当前事务ID并将其作为MDC变量传递给Logger框架。

因此,对于SLF4J,您可以使用put方法,如以下示例所示:

MDC.put("txId", String.format(" TxId: [%s]", transactionId(entityManager)));

MDC(映射式诊断上下文)ThreadLocal针对Java线程的作用类似,它允许您注册键/值对并将其限制在当前运行的线程中。当日志框架构建日志消息时,可以引用这些键/值对。

要将“txId”日志变量打印到日志中,我们需要在日志添加器模式中包含此变量:

<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>TRACE</level>
    </filter>
    <encoder>
        <Pattern>%-5p [%t]:%X{txId} %c{1} - %m%n</Pattern>
        <charset>UTF-8</charset>
    </encoder>
</appender>

%X{txId}模式用于引用txId日志变量。


INNODB_TRX 给出所有活动事务。我需要获取当前事务。 - Sunny Agarwal
DB2怎么样? - João Pedro Schmitt
我从未真正使用过DB2。坦白地说,我甚至不认识任何使用它的人。但是,如果你使用它,你可以相应地更新答案。成为你想在这个世界上看到的变化! - Vlad Mihalcea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接