Oracle
在使用Oracle时,您需要执行以下SQL查询:
SELECT RAWTOHEX(tx.xid)
FROM v$transaction tx
JOIN v$session s ON tx.ses_addr = s.saddr
v$transaction
视图提供有关当前运行的数据库事务的信息。但是,在我们的系统中可能有多个正在运行的事务,因此我们将
v$transaction
与
v$session
视图连接起来。
v$session
视图提供有关当前会话或数据库连接的信息。通过在
v$transaction
和
v$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