Nøglepunkter at forstå:
-
Alt er i en transaktion. Hvis du ikke eksplicit opretter en med
BEGIN
ogCOMMIT
(ellerROLLBACK
) en er oprettet til dig kun for den erklæring. -
Skrivebeskyttet
SELECT
s får ikke et fuldt transaktions-id, de får kun et virtuelt transaktions-id. Så selvom det er en transaktion,SELECT 1;
eller hvad der nu ikke øger transaktions-id-tælleren. -
Kalder
txid_current()
kræfter tildelingen af et transaktions-id, hvis et ikke allerede var tildelt. Så en skrivebeskyttet transaktion vil nu have et transaktions-id, hvor den tidligere ikke ville have det.
Selvfølgelig er txids også fordelt på tværs af sessioner. I praksis kan dit eksempel ovenfor muligvis få TXID'er på a+1 og a+429, hvis databasen er optaget.
Det er generelt ikke klogt at bruge transaktions-id'et til noget på applikationsniveau. Især:
Behandl xmin
og xmax
som interne felter på systemniveau, og behandle resultatet af txid_current()
som en meningsløs numerisk værdi.
Detaljer om korrekt og ukorrekt brug af xids
Du bør især aldrig:
- Sammenlign xids efter numerisk værdi for at drage enhver form for konklusion om deres rækkefølge;
- Tilføj eller træk transaktions-id'er fra;
- Sorter transaktions-id'er;
- Forøg eller formindsk transaktions-id'er
- Sammenlign en 32-bit
xid
indtastet felt med en 64-bitbigint
epoke-udvidet xid, selv for lighed.
Så fra et anvendelsesperspektiv er xids hverken monotone eller ordinale.
Du kan sikkert:
- sammenlign to 64-bit epoke-udvidede xider for lighed eller ulighed; og
- giv xids til
txid_status(...)
og andre funktioner, der er dokumenteret som at tage et xid
Pas på:PostgreSQL bruger 32-bit smalle xids som xid
type og 64-bit epoke-udvidede xids typisk repræsenteret som bigint
som dem, der returneres af txid_current()
. Sammenligning af disse for lighed vil generelt synes at virke på en ny databaseinstallation, men når først den første epokeomslutning har fundet sted, vil de ikke længere være ens. Pg giver dig ikke engang en nem måde at se xid-epoken på SQL-niveau; du skal:
select (txid_current() >> 32) AS xid_epoch;
for at få de øverste 32 bit af den epoke-udvidede xid rapporteret af txid_current()
.
Så ... uanset hvad du forsøger at gøre, er det sandsynligt, at transaktions-id'et ikke er den rigtige måde at gøre det på.