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
提供所有活动事务。我需要得到当前的交易记录。