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

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

我已经在Google上四处浏览,但找不到任何相关内容。基本上,我想掌握长期运行的事务。

[现在,我浏览information_schema.INNODB_TRX或查看show engine innodb status的输出以找到trx_id,然后打开general_logs以查看所有查询正在运行。

[有没有办法,我可以使用transaction_idjdbc在代码中保留此hibernate,以便可以将其记录在服务器日志中?

java mysql hibernate jdbc transactions
1个回答
4
投票

由于这是一个非常普遍的要求,所以我写了this article来详细介绍该主题。

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视图之间匹配会话地址,我们可以找到xid视图中v$transaction列给出的当前正在运行的事务标识符。

由于xid列的类型为RAW,因此我们正在使用RAWTOHEX将交易标识符二进制值转换为其十六进制表示形式。

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

因此,只读事务将不会分配事务标识符。有关撤消日志的更多详细信息,请签出this article

SQL Server

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

SELECT CONVERT(VARCHAR, CURRENT_TRANSACTION_ID())

由于CURRENT_TRANSACTION_ID函数返回BIGINT列值,因此我们正在使用CONVERT来获取其String表示形式。

PostgreSQL

使用PostgreSQL Server时,您可以执行以下SQL查询以获取当前的事务ID:

SELECT CAST(txid_current() AS text)

由于txid_current函数返回BIGINT列值,因此我们正在使用CAST来获取其String表示形式。

MySQL和MariaDB

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

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

innodb_trx目录中的information_schema视图提供有关当前正在运行的数据库事务的信息。由于我们的系统中可能正在运行多个事务,因此我们需要通过将会话或数据库连接标识符与当前正在运行的会话进行匹配来过滤事务行。

就像Oracle一样,从MySQL 5.6开始,只有读写事务才会获得事务标识符。

由于分配事务ID具有给定的开销,因此只读事务将跳过此过程。有关更多详细信息,请查看this article

此只读事务优化在MariaDB中的工作方式相同,这意味着仅将事务ID分配给读写事务。

HSQLDB

使用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线程中。基本上,MDC允许您注册局限于当前运行线程的键/值对,并且在日志记录框架生成日志消息时可以引用这些键/值对。

要将“ 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对数变量。

有关MDC日志记录的更多详细信息,您可以阅读this article

© www.soinside.com 2019 - 2024. All rights reserved.