Автор оригинала: Vlad Mihalcea.
В этой статье я покажу вам, как получить идентификатор текущей транзакции базы данных. Идентификатор транзакции очень полезен для ведения журнала, особенно если вы хотите сопоставить несколько записей журнала, выполняемых в контексте одной и той же транзакции базы данных.
Как получить идентификатор текущей транзакции базы данных @vlad_mihalcea https://t.co/DcCfWujDjB pic.twitter.com/r09PMC4bOz
Как я объяснял в этой статье , в реляционной базе данных транзакции являются обязательными. Даже если вы не объявите транзакцию базы данных, вы все равно будете ее использовать.
Единственное, что вы настраиваете, – это область транзакции. Таким образом, если вы явно не объявите границы транзакций, каждая инструкция SQL будет выполняться в отдельной транзакции базы данных, что означает, что вы собираетесь использовать режим автоматической фиксации.
Однако чаще всего для бизнес-варианта использования требуется выполнение нескольких инструкций SQL, и в этом случае режим автоматической фиксации не позволит базе данных выполнить откат всех инструкций, выполненных в контексте текущего запущенного бизнес-варианта использования.
По этой причине методы уровня обслуживания аннотируются аннотацией @Transactional .
Таким образом, при выполнении метода @Transactional
все операторы SQL, выполняемые в контексте текущего бизнес-варианта использования, будут совместно использовать одну и ту же транзакцию базы данных.
Вы можете получить идентификатор транзакции базы данных из базы данных с помощью SQL-запроса, относящегося к конкретной базе данных.
Оракул
При использовании Oracle вам необходимо выполнить следующий SQL-запрос:
SELECT RAWTOHEX(tx.xid) FROM v$transaction tx JOIN v$session s ON tx.ses_addr = s.saddr
Представление транзакция v$
содержит информацию о текущих транзакциях базы данных. Однако в нашей системе может выполняться несколько транзакций, и именно поэтому мы присоединяемся к транзакции v$
с помощью сеанса v$
.
В представлении v$session
содержится информация о нашем текущем сеансе или подключении к базе данных. Сопоставляя адрес сеанса между v$транзакцией
и v$сеансом
представлениями, мы можем найти идентификатор текущей текущей транзакции, указанный в столбце xid
в представлении v$транзакция
.
Поскольку столбец xid
имеет тип RAW
, мы используем RAWTOHEX
для преобразования двоичного значения идентификатора транзакции в его шестнадцатеричное представление.
Oracle назначает идентификатор транзакции только в том случае, если ему необходимо назначить сегмент отмены, что подразумевает выполнение инструкции INSERT, UPDATE или DELETE DML.
Таким образом, транзакциям, доступным только для чтения, не будет присвоен идентификатор транзакции. Для получения более подробной информации о журнале отмены ознакомьтесь с этой статьей .
SQL Server
При использовании SQL Server вам просто нужно выполнить следующий SQL-запрос:
SELECT CONVERT(VARCHAR, CURRENT_TRANSACTION_ID())
Поскольку функция CURRENT_TRANSACTION_ID
возвращает значение столбца BIGINT
, мы используем CONVERT
для получения его строкового представления.
PostgreSQL
При использовании сервера PostgreSQL вы можете выполнить следующий SQL-запрос, чтобы получить идентификатор текущей транзакции:
SELECT CAST(txid_current() AS text)
Поскольку функция tx id_current
возвращает значение столбца BIGINT
, мы используем CAST
для получения его строкового представления.
MySQL и MariaDB
При использовании MySQL или MariaDB вы можете выполнить следующий SQL-запрос, чтобы получить идентификатор текущей транзакции:
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, что означает, что идентификатор транзакции назначается только для транзакций только для чтения и записи.
HSQLDB
При использовании базы данных HyperSQL вы можете выполнить следующий SQL-запрос, чтобы получить идентификатор текущей транзакции:
VALUES (TRANSACTION_ID())
Вот и все!
Получение идентификатора текущей транзакции базы данных очень удобно, особенно если вы хотите регистрировать эту информацию для каждой выполняемой инструкции SQL.