Puntos clave para entender:
-
Todo está en una transacción. Si no crea uno explícitamente con
BEGIN
yCOMMIT
(oROLLBACK
) se crea uno para usted solo para esa declaración. -
Solo lectura
SELECT
s no obtienen una identificación de transacción completa, solo obtienen una identificación de transacción virtual. Entonces, aunque es una transacción,SELECT 1;
o lo que sea que no incremente el contador de ID de transacciones. -
Llamando a
txid_current()
fuerzas la asignación de un ID de transacción si aún no se ha asignado uno. Entonces, una transacción de solo lectura ahora tendrá una ID de transacción, donde antes no la tenía.
Por supuesto, los txid también se asignan entre sesiones. En la práctica, su ejemplo anterior podría obtener txid de a+1 y a+429 si la base de datos está ocupada.
Por lo general, no es aconsejable usar el ID de transacción para nada en el nivel de la aplicación. En particular:
Tratar xmin
y xmax
como campos de nivel de sistema interno y tratar el resultado de txid_current()
como un valor numérico sin sentido.
Detalles sobre usos correctos e incorrectos de xids
En particular, nunca debe:
- Compare xids por valor numérico para sacar cualquier tipo de conclusión sobre su orden;
- Sumar o restar ID de transacciones;
- Ordenar ID de transacciones;
- Aumentar o disminuir ID de transacciones
- Compara un
xid
de 32 bits campo escrito con unbigint
de 64 bits xid de época extendida, incluso para la igualdad.
Entonces, desde la perspectiva de la aplicación, los xids no son monótonos ni ordinales.
Tu puedes con seguridad:
- compare dos xid de época extendida de 64 bits para determinar la igualdad o la desigualdad; y
- pasar xids a
txid_status(...)
y otras funciones documentadas como tomando un xid
Cuidado:PostgreSQL usa xid estrechos de 32 bits como el xid
type, y los xid extendidos de época de 64 bits normalmente representados como bigint
como los devueltos por txid_current()
. La comparación de estos por igualdad generalmente parecerá funcionar en una nueva instalación de base de datos, pero una vez que se haya producido el primer ajuste de época, ya no serán iguales. Pg ni siquiera le brinda una manera fácil de ver la época xid en el nivel de SQL; tienes que:
select (txid_current() >> 32) AS xid_epoch;
para obtener los 32 bits superiores del xid extendido por época informado por txid_current()
.
Entonces... independientemente de lo que intente hacer, es probable que el ID de la transacción no sea la forma correcta de hacerlo.