PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Autorollback no postgres usando PDO


Isso não é culpa do PDO, é inerente ao gerenciamento de transações do PostgreSQL. Ver:
a>
  • Posso pedir ao Postgresql para ignorar erros em uma transação
  • Reversão após erro na transação

  • O PostgreSQL não reverte a transação, mas a configura para um estado abortado onde só pode reverter e onde todas as instruções, exceto ROLLBACK reportar um erro:

    (Estou surpreso por não encontrar isso mencionado na documentação oficial; acho que precisarei escrever um patch para melhorar isso.)

    Então. Quando você tenta/captura e engole a exceção no PDO, você está capturando uma exceção do lado do PHP, mas não está alterando o fato de que a transação do PostgreSQL está em um estado abortado.

    Se você quiser engolir exceções e continuar usando a transação, você deve criar um SAVEPOINT antes de cada instrução que pode falhar. Se falhar, você deve ROLLBACK TO SAVEPOINT ...; . Se for bem-sucedido, você pode RELEASE SAVEPOINT ...; . Isso impõe sobrecarga extra no banco de dados para gerenciamento de transações, adiciona viagens de ida e volta e queima IDs de transação mais rapidamente (o que significa que o PostgreSQL precisa fazer mais trabalho de limpeza em segundo plano).

    Geralmente, é preferível projetar seu SQL para que ele não falhe em circunstâncias normais. Por exemplo, você pode validar a maioria das restrições do lado do cliente, tratando as restrições do lado do servidor como um segundo nível de garantia enquanto captura a maioria dos erros do lado do cliente.

    Onde isso for impraticável, torne seu aplicativo tolerante a falhas, para que ele possa tentar novamente uma transação com falha. Às vezes, isso é necessário de qualquer maneira - por exemplo, você geralmente não pode usar pontos de salvamento para recuperar de deadlocks, abortos de transações ou falhas de serialização. Também pode ser útil manter as transações propensas a falhas o mais curtas possível, fazendo apenas o trabalho mínimo necessário, para que você tenha menos para acompanhar e repetir.

    Portanto:Sempre que possível, em vez de engolir uma exceção, execute o código de banco de dados propenso a falhas em um loop de repetição. Certifique-se de que seu código mantenha um registro das informações necessárias para tentar novamente toda a transação em caso de erro, não apenas a declaração mais recente.

    Lembre-se, qualquer a transação pode falhar:O DBA pode reiniciar o banco de dados para aplicar um patch, o sistema pode ficar sem RAM devido a um cron job descontrolado, etc. Portanto, aplicativos tolerantes a falhas são um bom design de qualquer maneira.

    Parabéns por pelo menos usar exceções de PDO e lidar com exceções - você já está muito à frente da maioria dos desenvolvedores.