PostgreSQL-Fehler: current transaction is aborted
ERROR: current transaction is aborted, commands ignored until end of transaction block
Dieser Fehler ist nie die eigentliche Ursache. Eine frühere Anweisung in derselben Transaktion ist bereits fehlgeschlagen, die Transaktion ist in den abgebrochenen Zustand übergegangen, und PostgreSQL weist nun jeden weiteren Befehl zurück, bis Sie die Transaktion mit ROLLBACK beenden. Die zu beantwortende Frage ist immer: was war der erste Fehler?
Was dieser Fehler bedeutet
Sobald irgendeine Anweisung innerhalb einer Transaktion fehlschlägt, garantiert PostgreSQL, dass die Transaktion als Ganzes nicht committen kann — weitere Anweisungen "gelingen" zu lassen, würde erlauben, eine halb angewandte Arbeitseinheit zu committen. Also verweigert es sie alle und wiederholt diese Meldung, bis die Anwendung ein ROLLBACK ausführt (oder zu einem vor dem Fehler gesetzten Savepoint zurückrollt).
Wenn Sie Fluten von 25P02 in Ihren Logs sehen, lesen Sie sie als Symptom mit zwei Schichten: einem ursprünglichen Fehler (eine Zeile, leicht zu übersehen) und einer Anwendung, die die Verbindung weiterverwendet hat, als wäre nichts geschehen (die Flut).
Häufige Ursachen
- Die Anwendung schluckt die erste Ausnahme — ein try/catch, das loggt und weitermacht, immer noch innerhalb der Transaktion, immer noch auf derselben Verbindung.
- Framework- oder Treibercode, der bei einem Fehler nicht zurückrollt, bevor er die Sitzung wiederverwendet.
- Ein Connection-Pool, der eine in einer fehlgeschlagenen Transaktion feststeckende Verbindung ausgibt, weil er den Zustand bei der Freigabe nicht zurücksetzt.
- psql-Skripte, die innerhalb von
BEGIN ... COMMITlaufen und nach einem Fehler weitermachen (standardmäßig macht psql weiter).
So diagnostizieren Sie ihn
- Im Server-Log schauen Sie, was dieselbe Sitzung kurz vor der 25P02-Flut getan hat — mit
%p(PID) inlog_line_prefixkönnen Sie der Sitzung folgen; der ersteERRORvon dieser PID ist Ihr eigentliches Problem. - In der Anwendung protokollieren und untersuchen Sie die erste Ausnahme, nicht die nachfolgenden: eine sehr häufige Paarung ist eine Verletzung eines Unique-Constraints, gefolgt von einem Strom von 25P02 aus Code, der sie "behandelt" hat und weitergezogen ist.
- Interaktiv in psql ist der ursprüngliche Fehler einfach der direkt darüber gedruckte.
So beheben Sie ihn
- Bei jedem Anweisungsfehler zurückrollen — dann die gesamte Transaktion wiederholen, falls angebracht. Strukturieren Sie den Code so, dass eine Ausnahme innerhalb einer Transaktion nicht gefangen werden kann, ohne die Transaktion zu beenden.
- Erwartete Fehlschläge → Savepoints, damit ein Fehlschlag die Transaktion nicht vergiftet:
Besser noch: wenn der erwartete Fehlschlag ein Duplikat ist, verwenden SieBEGIN; SAVEPOINT attempt; INSERT INTO users ...; -- kann fehlschlagen -- im Fehlerfall: ROLLBACK TO SAVEPOINT attempt; -- die Transaktion bleibt nutzbar COMMIT;ON CONFLICTund vermeiden Sie den Fehler ganz. - Skripte: führen Sie psql mit
ON_ERROR_STOPaus (psql -v ON_ERROR_STOP=1), damit ein Fehler das Skript stoppt statt zu kaskadieren; interaktiv lässt\set ON_ERROR_ROLLBACK interactivepsql Anweisungen für Sie in Savepoints kapseln. - Pools: stellen Sie sicher, dass Verbindungen bei der Rückgabe an den Pool zurückgerollt/zurückgesetzt werden (z. B.
DISCARD ALL).
