Основни моменти, които трябва да разберете:
-
Всичко е в сделка. Ако не създадете изрично такъв с
BEGIN
иCOMMIT
(илиROLLBACK
) един е създаден за вас само за това изявление. -
Само за четене
SELECT
s не получават пълен идентификатор на транзакцията, те получават само виртуален идентификатор на транзакция. Така че, въпреки че е транзакция,SELECT 1;
или каквото и да е, което не увеличава брояча на идентификатора на транзакцията. -
Извикване на
txid_current()
сили разпределението на идентификатор на транзакция, ако такъв все още не е разпределен. Така че транзакцията само за четене вече ще има идентификатор на транзакцията, където преди не би.
Разбира се, txids също се разпределят между сесиите. На практика вашият пример по-горе може да получи txid от a+1 и a+429, ако базата данни е заета.
По принцип не е разумно да използвате идентификатора на транзакцията за каквото и да било на ниво приложение. По-специално:
Третирайте xmin
и xmax
като полета на вътрешно системно ниво и третирайте резултата от txid_current()
като безсмислена числова стойност.
Подробности за правилното и неправилното използване на xids
По-специално, никога не трябва да:
- Сравнете xids по числова стойност, за да направите каквото и да е заключение относно тяхното подреждане;
- Добавяне или изваждане на идентификатори на транзакции;
- Сортиране на идентификатори на транзакции;
- Увеличете или намалете идентификаторите на транзакции
- Сравнете 32-битов
xid
въведено поле с 64-битовbigint
xid с разширен епоха, дори за равенство.
Така че от гледна точка на приложението xids не са нито монотонни, нито ординални.
Вие можете безопасно:
- сравнете два 64-битови xid с разширени епохи за равенство или неравенство; и
- предаване на xids към
txid_status(...)
и други функции, документирани като приемане на xid
Внимавайте:PostgreSQL използва 32-битови тесни xid като xid
тип и 64-битови xids с разширени епохи, обикновено представени като bigint
като тези, върнати от txid_current()
. Сравняването им за равенство обикновено изглежда работи при инсталиране на нова база данни, но след като настъпи първата епоха и те вече няма да са равни. Pg дори не ви дава лесен начин да видите епохата на xid на ниво SQL; трябва да:
select (txid_current() >> 32) AS xid_epoch;
за да получите горните 32 бита на xid с разширение на епохата, докладван от txid_current()
.
Така че... каквото и да се опитвате да направите, вероятно идентификационният номер на транзакцията не е правилният начин да го направите.