Kluczowe punkty do zrozumienia:
-
Wszystko jest w transakcji. Jeśli nie utworzysz go jawnie za pomocą
BEGIN
iCOMMIT
(lubROLLBACK
) jeden jest stworzony dla Ciebie tylko dla tego oświadczenia. -
Tylko do odczytu
SELECT
s nie otrzymują pełnego identyfikatora transakcji, otrzymują tylko wirtualny identyfikator transakcji. Więc nawet jeśli jest to transakcja,SELECT 1;
lub cokolwiek, co nie zwiększa licznika identyfikatora transakcji. -
Wywołanie
txid_current()
siły przydział identyfikatora transakcji, jeśli nie został jeszcze przydzielony. Tak więc transakcja tylko do odczytu będzie miała teraz identyfikator transakcji, którego wcześniej nie miała.
Oczywiście txids są również przydzielane między sesjami. W praktyce powyższy przykład może otrzymać txid a+1 i a+429, jeśli baza danych jest zajęta.
Generalnie nie jest rozsądne używanie identyfikatora transakcji do czegokolwiek na poziomie aplikacji. W szczególności:
Traktuj xmin
i xmax
jako wewnętrzne pola poziomu systemu i traktuj wynik txid_current()
jako bezsensowna wartość liczbowa.
Szczegóły dotyczące poprawnych i nieprawidłowych zastosowań xids
W szczególności nigdy nie powinieneś:
- Porównaj xids według wartości liczbowej, aby wyciągnąć jakiekolwiek wnioski dotyczące ich kolejności;
- Dodaj lub odejmij identyfikatory transakcji;
- Sortuj identyfikatory transakcji;
- Zwiększanie lub zmniejszanie identyfikatorów transakcji
- Porównaj 32-bitowy
xid
wpisane pole z 64-bitowymbigint
xid z rozszerzeniem epoki, nawet dla równości.
Więc z perspektywy aplikacji xids nie są ani monotoniczne, ani porządkowe.
możesz bezpiecznie:
- porównaj dwa 64-bitowe xid rozszerzone o epokę pod kątem równości lub nierówności; i
- przekaż xids do
txid_status(...)
i inne funkcje udokumentowane jako pobieranie xid
Uwaga:PostgreSQL używa 32-bitowych wąskich xidów, takich jak xid
typ i 64-bitowe xidy rozszerzone o epokę zwykle reprezentowane jako bigint
jak te zwrócone przez txid_current()
. Porównywanie ich pod kątem równości na ogół wydaje się działać w przypadku nowej instalacji bazy danych, ale po wystąpieniu pierwszego okrążenia epoki i nie będą one już równe. Pg nie daje nawet łatwego sposobu na zobaczenie epoki xid na poziomie SQL; musisz:
select (txid_current() >> 32) AS xid_epoch;
aby uzyskać górne 32 bity xid rozszerzonego okresu epoki raportowane przez txid_current()
.
Więc ... cokolwiek próbujesz zrobić, prawdopodobnie identyfikator transakcji nie jest właściwym sposobem.