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

Java 如何使用JDBC或Hibernate获取当前数据库事务id?,java,mysql,hibernate,jdbc,transactions,Java,Mysql,Hibernate,Jdbc,Transactions,我在谷歌上搜索过这个,但找不到任何相关的东西。基本上,我希望获得长时间运行的事务 现在,我通过查看information\u schema.INNODB\u TRX或查看show engine INNODB status的输出,找到TRX\u id,然后打开general\u logs,查看所有查询都在运行 有没有办法,我可以使用jdbc或hibernate在我的代码中获得这个transaction\u id,这样我就可以将它记录到我的服务器日志中?Oracle 使用Oracle时,必须执行以下

我在谷歌上搜索过这个,但找不到任何相关的东西。基本上,我希望获得长时间运行的事务

现在,我通过查看
information\u schema.INNODB\u TRX
或查看
show engine INNODB status
的输出,找到
TRX\u id
,然后打开
general\u logs
,查看所有查询都在运行

有没有办法,我可以使用
jdbc
hibernate
在我的代码中获得这个
transaction\u id
,这样我就可以将它记录到我的服务器日志中?

Oracle 使用Oracle时,必须执行以下SQL查询:

SELECT RAWTOHEX(tx.xid)
FROM v$transaction tx
JOIN v$session s ON tx.ses_addr = s.saddr
SELECT CONVERT(VARCHAR, CURRENT_TRANSACTION_ID())
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 RAWTOHEX(tx.xid)
FROM v$transaction tx
JOIN v$session s ON tx.ses_addr = s.saddr
SELECT CONVERT(VARCHAR, CURRENT_TRANSACTION_ID())
因为
CURRENT\u TRANSACTION\u ID
函数返回一个
BIGINT
列值,所以我们使用
CONVERT
来获取它的字符串表示形式

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

SELECT CAST(txid_current() AS text)
SELECT tx.trx_id
FROM information_schema.innodb_trx tx
WHERE tx.trx_mysql_thread_id = connection_id()
VALUES (TRANSACTION_ID())
由于
txid\u current
函数返回一个
BIGINT
列值,因此我们使用
CAST
来获取其字符串表示形式

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

SELECT CAST(txid_current() AS text)
SELECT tx.trx_id
FROM information_schema.innodb_trx tx
WHERE tx.trx_mysql_thread_id = connection_id()
VALUES (TRANSACTION_ID())
information\u schema
目录中的
innodb\u trx
视图提供有关当前运行的数据库事务的信息。由于系统中可能有多个事务在运行,因此我们需要通过将会话或数据库连接标识符与当前运行的会话相匹配来过滤事务行

就像Oracle一样,自MySQL 5.6以来,只有读写事务才会获得事务标识符

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

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

HSQLDB 使用HyperSQL数据库时,可以执行以下SQL查询以获取当前事务id:

SELECT CAST(txid_current() AS text)
SELECT tx.trx_id
FROM information_schema.innodb_trx tx
WHERE tx.trx_mysql_thread_id = connection_id()
VALUES (TRANSACTION_ID())
使用MDC记录事务id 事务id对于日志记录非常有用,因为它允许我们聚合在给定数据库事务上下文中执行的所有操作

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

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

MDC.put("txId", String.format(" TxId: [%s]", transactionId(entityManager)));
用于记录Java线程的
ThreadLocal
功能。基本上,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>

痕迹
%-5p[%t]:%X{txId}%c{1}-%m%n
UTF-8

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

INNODB\u TRX
提供所有活动事务。我需要得到当前的交易记录。