Viktiga punkter att förstå:
-
Allt är i en transaktion. Om du inte uttryckligen skapar en med
BEGIN
ochCOMMIT
(ellerROLLBACK
) en skapas för dig bara för det påståendet. -
Skrivskyddad
SELECT
s får inte ett fullständigt transaktions-ID, de får bara ett virtuellt transaktions-ID. Så även om det är en transaktion,SELECT 1;
eller något som inte ökar transaktions-ID-räknaren. -
Anropar
txid_current()
krafter tilldelningen av ett transaktions-ID om ett sådant inte redan tilldelats. Så en skrivskyddad transaktion kommer nu att ha ett transaktions-ID, där den tidigare inte hade det.
Naturligtvis fördelas txids också över sessioner. I praktiken kan ditt exempel ovan få TXID:s på a+1 och a+429 om databasen är upptagen.
Det är i allmänhet inte klokt att använda transaktions-ID för något på applikationsnivå. I synnerhet:
Behandla xmin
och xmax
som interna systemnivåfält, och behandla resultatet av txid_current()
som ett meningslöst numeriskt värde.
Detaljer om korrekt och felaktig användning av xids
I synnerhet bör du aldrig:
- Jämför xids efter numeriskt värde för att dra någon form av slutsats om deras ordning;
- Lägg till eller subtrahera transaktions-ID:n;
- Sortera transaktions-ID:n;
- Öka eller minska transaktions-ID:n
- Jämför en 32-bitars
xid
inskrivet fält med en 64-bitarsbigint
epokförlängd xid, även för jämlikhet.
Så ur ett tillämpningsperspektiv är xids varken monotona eller ordinala.
Du kan säkert:
- jämför två 64-bitars epokförlängda xids för likhet eller ojämlikhet; och
- sänd xids till
txid_status(...)
och andra funktioner som dokumenteras som att ta ett xid
Se upp:PostgreSQL använder 32-bitars smala xids som xid
typ och 64-bitars epokförlängda xids som vanligtvis representeras som bigint
som de som returneras av txid_current()
. Att jämföra dessa för jämlikhet verkar i allmänhet fungera på en ny databasinstallation, men när den första epokomslutningen har inträffat kommer de inte längre att vara lika. Pg ger dig inte ens ett enkelt sätt att se xid-epoken på SQL-nivå; du måste:
select (txid_current() >> 32) AS xid_epoch;
för att få de övre 32 bitarna av den epokförlängda xid rapporterad av txid_current()
.
Så ... vad du än försöker göra, är det troligt att transaktions-ID:t inte är rätt sätt att göra det.