PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PSQLException:Aktuelle Transaktion wird abgebrochen, Befehle werden bis zum Ende des Transaktionsblocks ignoriert

Ich habe diesen Fehler mit Java und PostgreSQL beim Einfügen in eine Tabelle erhalten. Ich werde veranschaulichen, wie Sie diesen Fehler reproduzieren können:

org.postgresql.util.PSQLException: ERROR: 
current transaction is aborted, commands ignored until end of transaction block

Zusammenfassung:

Der Grund, warum Sie diesen Fehler erhalten, ist, dass Sie eine Transaktion eingegeben haben und eine Ihrer SQL-Abfragen fehlgeschlagen ist, und Sie diesen Fehler verschlungen und ignoriert haben. Aber das war nicht genug, DANN haben Sie dieselbe Verbindung verwendet und die GLEICHE TRANSAKTION verwendet, um eine andere Abfrage auszuführen. Die Ausnahme wird bei der zweiten, korrekt formatierten Abfrage ausgelöst, da Sie eine fehlerhafte Transaktion verwenden, um zusätzliche Arbeit zu leisten. PostgreSQL hält Sie standardmäßig davon ab.

Ich verwende: PostgreSQL 9.1.6 on x86_64-redhat-linux-gnu, compiled by gcc (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2), 64-bit".

Mein PostgreSQL-Treiber ist: postgresql-9.2-1000.jdbc4.jar

Mit Java-Version: Java 1.7

Hier ist die Tabellenerstellungsanweisung zur Veranschaulichung der Ausnahme:

CREATE TABLE moobar
(
    myval   INT
);

Java-Programm verursacht den Fehler:

public void postgresql_insert()
{
    try  
    {
        connection.setAutoCommit(false);  //start of transaction.
        
        Statement statement = connection.createStatement();
        
        System.out.println("start doing statement.execute");
        
        statement.execute(
                "insert into moobar values(" +
                "'this SQL statement fails, and it " +
                "is gobbled up by the catch, okfine'); ");
     
        //The above line throws an exception because we try to cram
        //A string into an Int.  I Expect this, what happens is we gobble 
        //the Exception and ignore it like nothing is wrong.
        //But remember, we are in a TRANSACTION!  so keep reading.

        System.out.println("statement.execute done");
        
        statement.close();
        
    }
    catch (SQLException sqle)
    {
        System.out.println("keep on truckin, keep using " +
                "the last connection because what could go wrong?");
    }
    
    try{
        Statement statement = connection.createStatement();
        
        statement.executeQuery("select * from moobar");

        //This SQL is correctly formed, yet it throws the 
        //'transaction is aborted' SQL Exception, why?  Because:
        //A.  you were in a transaction.
        //B.  You ran a SQL statement that failed.
        //C.  You didn't do a rollback or commit on the affected connection.
        
    }
    catch (SQLException sqle)
    {
        sqle.printStackTrace();
    }   

}

Der obige Code erzeugt diese Ausgabe für mich:

start doing statement.execute

keep on truckin, keep using the last connection because what could go wrong?

org.postgresql.util.PSQLException: 
  ERROR: current transaction is aborted, commands ignored until 
  end of transaction block

Problemumgehungen:

Sie haben einige Möglichkeiten:

  1. Einfachste Lösung:Beteiligen Sie sich nicht an einer Transaktion. Legen Sie connection.setAutoCommit(false); fest zu connection.setAutoCommit(true); . Es funktioniert, weil dann die fehlgeschlagene SQL einfach als fehlgeschlagene SQL-Anweisung ignoriert wird. Sie können SQL-Anweisungen beliebig oft fehlschlagen lassen, und PostgreSQL wird Sie nicht aufhalten.

  2. Bleiben Sie in einer Transaktion, aber wenn Sie feststellen, dass die erste SQL fehlgeschlagen ist, führen Sie entweder ein Rollback/Neustart oder Commit/Neustart der Transaktion durch. Dann können Sie weiterhin so viele SQL-Abfragen auf dieser Datenbankverbindung fehlschlagen lassen, wie Sie möchten.

  3. Fangen und ignorieren Sie nicht die Ausnahme, die ausgelöst wird, wenn eine SQL-Anweisung fehlschlägt. Dann stoppt das Programm bei der fehlerhaften Abfrage.

  4. Holen Sie sich stattdessen Oracle, Oracle löst keine Ausnahme aus, wenn eine Abfrage für eine Verbindung innerhalb einer Transaktion fehlschlägt, und verwenden Sie diese Verbindung weiter.

Zur Verteidigung der Entscheidung von PostgreSQL, die Dinge auf diese Weise zu tun ... Oracle war macht dich weich in der Mitte, lässt dich dummes Zeug machen und übersieht es.