Tecnología · GUÍA PRÁCTICA
¿PostgreSQL SQLSTATE 40001? Reintente toda la transacción, no la sentencia fallida
Registre SQLSTATE, aislamiento y límite del fallo; revierta y repita cada lectura y decisión con un presupuesto acotado, dejando los efectos irreversibles después del commit.

SQLSTATE 40001 es serialization_failure en PostgreSQL. Puede aparecer con Repeatable Read o Serializable y puede llegar durante COMMIT. La base rechazó el intento completo; repetir solo la última sentencia reutiliza decisiones derivadas de una instantánea que ya no es válida.
Un controlador seguro envuelve el callback completo y COMMIT: confirma 40001, revierte, espera con backoff y jitter acotados, inicia otra transacción y repite lecturas, decisiones y escrituras. PostgreSQL no puede reconstruir automáticamente la lógica que eligió SQL y valores.
Reintentar no debe ocultar contención. Fije un límite de intentos o tiempo, mida y exponga el agotamiento. Correo, cobros, publicación y otros efectos irreversibles deben ir después del commit; un outbox transaccional o clave de idempotencia conecta el estado confirmado con la entrega.
Registre el límite del fallo antes de reintentar
Registre SQLSTATE, aislamiento, intento, edad de la transacción y si falló una sentencia o COMMIT. Controle por código, no por texto traducido.
Un fallo en COMMIT es posible: el servidor puede necesitar el conjunto completo de lecturas y escrituras para decidir el orden seguro.
Repita desde BEGIN con lecturas nuevas
Tras rollback, vuelva a la primera lectura. Recalcule existencia, inventario, precios, autorización y valores derivados. Repetir solo UPDATE o un savepoint conserva supuestos inválidos.
Haga que una invocación del callback sea un intento y capture tanto callback como COMMIT.
Acote los intentos y muestre la contención
Use pocos intentos o tiempo total, backoff y jitter. Reinicie el estado en cada intento y no reutilice una transacción abortada.
Mida por operación. El agotamiento exige revisar transacciones largas, claves calientes, índices, pool y necesidad de aislamiento; no reduzca aislamiento como parche.
Deje efectos fuera del límite seguro de commit
El callback puede ejecutarse varias veces. No envíe correo, cobre, publique ni llame API no idempotentes antes del commit.
Escriba un outbox en la misma transacción y publique después. Use una clave de idempotencia derivada de la solicitud estable del negocio.
Separe los SQLSTATE vecinos
40P01 es deadlock: puede reintentarse pero requiere revisar el orden de bloqueos. 23505 necesita prueba de la aplicación antes de automatizar.
40003 indica resultado desconocido y exige reconciliar antes de repetir. Reintentar toda la clase 40 puede duplicar trabajo.
