简体   繁体   English

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

[英]How to get the current database transaction id using JDBC or Hibernate?

I've looked around on Google for this but couldn't find anything relevant.我在谷歌上环顾四周,但找不到任何相关的东西。 Basically, I want to get hold of long running transactions.基本上,我想掌握长时间运行的事务。

For now, I go through information_schema.INNODB_TRX or have a look at the output of show engine innodb status to find the trx_id and then turn on general_logs to see what all queries are running.现在,我通过information_schema.INNODB_TRX或查看show engine innodb status的输出以找到trx_id ,然后打开general_logs以查看所有查询正在运行的内容。

Is there a way, I can get hold of this transaction_id in my code using jdbc or hibernate so that I can log it in my server logs?有没有办法,我可以使用jdbchibernate在我的代码中获取这个transaction_id ,以便我可以将它记录在我的服务器日志中?

Oracle甲骨文

When using Oracle, you have to execute the following SQL query:使用 Oracle 时,必须执行以下 SQL 查询:

SELECT RAWTOHEX(tx.xid)
FROM v$transaction tx
JOIN v$session s ON tx.ses_addr = s.saddr

The v$transaction view provides information about the currently running database transactions. v$transaction视图提供有关当前运行的数据库事务的信息。 However, there can be multiple transactions running in our system, and that's why we are joining the v$transaction with the v$session view.然而,在我们的系统中可能有多个事务在运行,这就是我们将v$transactionv$session视图连接起来的原因。

The v$session view offers information about our current session or database connection. v$session视图提供有关我们当前会话或数据库连接的信息。 By matching the session address between the v$transaction and v$session views, we can find the current running transaction identifier given by the xid column in the v$transaction view.通过匹配v$transactionv$session视图之间的会话地址,我们可以找到v$transaction视图中xid列给出的当前正在运行的事务标识符。

Because the xid column is of type RAW , we are using RAWTOHEX to convert the transaction identifier binary value to its hexadecimal representation.因为xid列是RAW类型,所以我们使用RAWTOHEX将交易标识符二进制值转换为其十六进制表示。

Oracle assigns a transaction identifier only if it needs to assign an undo segment, which implies that an INSERT, UPDATE or DELETE DML statement has been executed. Oracle 仅在需要分配撤消段时才分配事务标识符,这意味着已经执行了 INSERT、UPDATE 或 DELETE DML 语句。

So, read-only transactions will not have a transaction identifier assigned.因此,只读事务不会分配事务标识符。

SQL Server数据库服务器

When using SQL Server, you just have to execute the following SQL query:使用 SQL Server 时,您只需执行以下 SQL 查询:

SELECT CONVERT(VARCHAR, CURRENT_TRANSACTION_ID())

Because the CURRENT_TRANSACTION_ID function returns a BIGINT column value, we are using CONVERT to get its String representation.因为CURRENT_TRANSACTION_ID函数返回一个BIGINT列值,所以我们使用CONVERT来获取其字符串表示。

PostgreSQL PostgreSQL

When using PostgreSQL Server, you can execute the following SQL query to get the current transaction id:使用 PostgreSQL Server 时,您可以执行以下 SQL 查询来获取当前事务 id:

SELECT CAST(txid_current() AS text)

Because the txid_current function returns a BIGINT column value, we are using CAST to get its String representation.因为txid_current函数返回一个BIGINT列值,所以我们使用CAST来获取它的字符串表示。

MySQL and MariaDB MySQL 和 MariaDB

When using MySQL or MariaDB, you can execute the following SQL query to get the current transaction id:在使用 MySQL 或 MariaDB 时,您可以执行以下 SQL 查询来获取当前事务 id:

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

The innodb_trx view in the information_schema catalog provides information about the currently running database transactions. information_schema目录中的innodb_trx视图提供有关当前运行的数据库事务的信息。 Since there can be multiple transactions running in our system, we need to filter the transaction rows by matching the session or database connection identifier with the currently running session.由于我们的系统中可以运行多个事务,我们需要通过将会话或数据库连接标识符与当前正在运行的会话进行匹配来过滤事务行。

Just like it was the case with Oracle, since MySQL 5.6, only read-write transactions will get a transaction identifier.就像 Oracle 的情况一样,从 MySQL 5.6 开始,只有读写事务才能获得事务标识符。

Because assigning a transaction id has a given overhead, read-only transactions skip this process.因为分配一个事务 id 有一个给定的开销,只读事务跳过这个过程。 For more details, check out this article .有关更多详细信息,请查看这篇文章

This read-only transaction optimization works the same way in MariaDB, meaning that a transaction id is only assigned for read-write transactions only.这种只读事务优化在 MariaDB 中的工作方式相同,这意味着事务 id 仅分配给读写事务。

HSQLDB数据库

When using the HyperSQL database, you can execute the following SQL query to get the current transaction id:使用 HyperSQL 数据库时,可以执行以下 SQL 查询来获取当前事务 id:

VALUES (TRANSACTION_ID())

Logging the transaction id using MDC使用 MDC 记录事务 ID

The transaction id is useful for logging because it allows us to aggregate all actions that were executed in the context of a given database transaction.事务 id 对记录很有用,因为它允许我们聚合在给定数据库事务的上下文中执行的所有操作。

Assuming we have encapsulated the SQL queries above in atransactionId method, we could extract the current transaction id and pass it to the Logger framework as an MDC variable.假设我们已经将上面的 SQL 查询封装在一个transactionId方法中,我们可以提取当前事务 id 并将其作为 MDC 变量传递给 Logger 框架。

So, for SLF4J, you can use the put method as illustrated by the following example:因此,对于 SLF4J,您可以使用put方法,如下例所示:

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

MDC (Mapped Diagnostic Context) is for logging what ThreadLocal is to Java threads. MDC(映射诊断上下文)用于记录ThreadLocal对 Java 线程的意义。 Basically, MDC allows you to register key/value pairs that are confined to the currently running thread and which you can reference when the logging framework builds log messages.基本上,MDC 允许您注册仅限于当前正在运行的线程的键/值对,您可以在日志框架构建日志消息时引用这些键/值对。

To print the "txId" log variable to the log, we need to include this variable in the log appender pattern:要将“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>

The %X{txId} pattern is used to reference the txId log variable. %X{txId}模式用于引用txId日志变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM