sql >> Base de Datos >  >> RDS >> PostgreSQL

Autorollback en postgres usando PDO

Eso no es culpa de PDO, es inherente a la gestión de transacciones de PostgreSQL. Ver:

PostgreSQL no revierte la transacción, pero la establece en un estado abortado en el que solo se puede revertir, y donde todas las declaraciones excepto ROLLBACK informar de un error:

(Me sorprende que no se haga referencia a esto en la documentación oficial; creo que tendré que escribir un parche para mejorarlo).

Asi que. Cuando intenta/atrapa y traga la excepción en PDO, está atrapando una excepción del lado de PHP, pero no está cambiando el hecho de que la transacción de PostgreSQL está en un estado abortado.

Si desea poder aceptar excepciones y seguir usando la transacción, debe crear un SAVEPOINT antes de cada declaración que podría fallar. Si falla, debe ROLLBACK TO SAVEPOINT ...; . Si tiene éxito, puede RELEASE SAVEPOINT ...; . Esto impone una sobrecarga adicional en la base de datos para la administración de transacciones, agrega viajes de ida y vuelta y procesa los ID de transacción más rápido (lo que significa que PostgreSQL tiene que hacer más trabajo de limpieza en segundo plano).

En general, es preferible diseñar su SQL para que no falle en circunstancias normales. Por ejemplo, puede validar la mayoría de las restricciones del lado del cliente, tratando las restricciones del lado del servidor como un segundo nivel de seguridad mientras captura la mayoría de los errores del lado del cliente.

Cuando eso no sea práctico, haga que su aplicación sea tolerante a fallas, para que pueda volver a intentar una transacción fallida. A veces, esto es necesario de todos modos; por ejemplo, generalmente no puede usar puntos de guardado para recuperarse de interbloqueos, cancelaciones de transacciones o fallas de serialización. También puede ser útil mantener las transacciones propensas a fallas lo más cortas posible, haciendo solo el trabajo mínimo requerido, para que tenga menos para realizar un seguimiento y repetir.

Entonces:Siempre que sea posible, en lugar de aceptar una excepción, ejecute el código de la base de datos propenso a fallas en un bucle de reintento. Asegúrese de que su código mantenga un registro de la información que necesita para volver a intentar toda la transacción en caso de error, no solo la declaración más reciente.

Recuerda, cualquiera la transacción puede fallar:el DBA podría reiniciar la base de datos para aplicar un parche, el sistema podría quedarse sin RAM debido a un trabajo cron fuera de control, etc. Por lo tanto, las aplicaciones tolerantes a fallas son un buen diseño de todos modos.

Gracias por al menos usar excepciones PDO y manejar excepciones:ya está muy por delante de la mayoría de los desarrolladores.