如何獲取當前資料庫事務ID - Vlad Mihalcea
在本文中,我將向您展示如何獲取當前資料庫事務ID。事務ID對於日誌記錄非常有用,尤其是如果要關聯在同一資料庫事務的上下文中執行的多個日誌條目。
事務基礎
在關係資料庫中,事務是必需的。即使您沒有宣告資料庫事務,您仍然會被預設使用了一個事務。
您可自己配置的唯一事務是事務範圍作用域。因此,如果您未明確宣告事務邊界,則每個SQL語句將在其自己的資料庫事務中執行,這意味著您將使用自動提交模式。
但是,大多數情況下,業務用例需要執行多個SQL語句,在這種情況下,自動提交模式將阻止資料庫能夠回滾在當前執行的業務用例的上下文中執行的所有語句。
因此,服務層方法使用註釋進行@Transactional註釋 。在執行@Transactional方法時,在當前業務用例的上下文中執行的所有SQL語句將共享相同的資料庫事務。
獲取事務ID
您可以使用特定於資料庫的SQL查詢從資料庫中獲取資料庫事務識別符號。
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檢視之間的會話地址,我們可以找到檢視中xid列所給出的當前執行事務識別符號v$transaction。
xid列是型別RAW,我們RAWTOHEX用於將事務識別符號二進位制值轉換為其十六進位制表示。
Oracle僅在需要分配撤消段時才分配事務識別符號,這意味著已執行INSERT,UPDATE或DELETE DML語句。
因此,只讀事務不會分配事務識別符號。有關撤消日誌的更多詳細資訊,請檢視此文章 。
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以來,只有讀寫事務才能獲得事務識別符號。
由於分配事務標識具有給定的開銷,因此只讀事務會跳過此過程。有關更多詳細資訊,請檢視此文章。
此只讀事務優化在MariaDB中的工作方式相同,這意味著事務ID僅分配給讀寫事務。
HSQLDB
使用HyperSQL資料庫時,可以執行以下SQL查詢以獲取當前事務ID:
VALUES (TRANSACTION_ID())