Основни моменти, които трябва да разберете:
-
Всичко е в сделка. Ако не създадете изрично такъв с
BEGINиCOMMIT(илиROLLBACK) един е създаден за вас само за това изявление. -
Само за четене
SELECTs не получават пълен идентификатор на транзакцията, те получават само виртуален идентификатор на транзакция. Така че, въпреки че е транзакция,SELECT 1;или каквото и да е, което не увеличава брояча на идентификатора на транзакцията. -
Извикване на
txid_current()сили разпределението на идентификатор на транзакция, ако такъв все още не е разпределен. Така че транзакцията само за четене вече ще има идентификатор на транзакцията, където преди не би.
Разбира се, txids също се разпределят между сесиите. На практика вашият пример по-горе може да получи txid от a+1 и a+429, ако базата данни е заета.
По принцип не е разумно да използвате идентификатора на транзакцията за каквото и да било на ниво приложение. По-специално:
Третирайте xmin и xmax като полета на вътрешно системно ниво и третирайте резултата от txid_current() като безсмислена числова стойност.
Подробности за правилното и неправилното използване на xids
По-специално, никога не трябва да:
- Сравнете xids по числова стойност, за да направите каквото и да е заключение относно тяхното подреждане;
- Добавяне или изваждане на идентификатори на транзакции;
- Сортиране на идентификатори на транзакции;
- Увеличете или намалете идентификаторите на транзакции
- Сравнете 32-битов
xidвъведено поле с 64-битовbigintxid с разширен епоха, дори за равенство.
Така че от гледна точка на приложението 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() .
Така че... каквото и да се опитвате да направите, вероятно идентификационният номер на транзакцията не е правилният начин да го направите.