sql >> Database >  >> RDS >> PostgreSQL

PSQLEException:huidige transactie wordt afgebroken, opdrachten worden genegeerd tot einde transactieblok

Ik kreeg deze fout bij het gebruik van Java en PostgreSQL bij het invoegen op een tafel. Ik zal illustreren hoe u deze fout kunt reproduceren:

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

Samenvatting:

De reden dat u deze fout krijgt, is omdat u een transactie hebt ingevoerd en een van uw SQL-query's is mislukt, en u heeft die fout opgeslokt en genegeerd. Maar dat was niet genoeg, DAN gebruikte je dezelfde verbinding en gebruikte DEZELFDE TRANSACTIE om een ​​andere query uit te voeren. De uitzondering wordt gegenereerd op de tweede, correct gevormde query omdat u een verbroken transactie gebruikt om extra werk te doen. PostgreSQL zorgt er standaard voor dat u dit niet doet.

Ik gebruik: 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".

Mijn PostgreSQL-stuurprogramma is: postgresql-9.2-1000.jdbc4.jar

Java-versie gebruiken: Java 1.7

Hier is de tabel create statement om de Exception te illustreren:

CREATE TABLE moobar
(
    myval   INT
);

Java-programma veroorzaakt de fout:

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();
    }   

}

De bovenstaande code produceert deze uitvoer voor mij:

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

Oplossingen:

Je hebt een paar opties:

  1. Eenvoudigste oplossing:doe geen transactie. Stel de connection.setAutoCommit(false); . in naar connection.setAutoCommit(true); . Het werkt omdat de mislukte SQL dan gewoon wordt genegeerd als een mislukte SQL-instructie. U bent van harte welkom om SQL-statements te laten mislukken wat u wilt en PostgreSQL zal u niet stoppen.

  2. Blijf in een transactie, maar wanneer u merkt dat de eerste SQL is mislukt, kunt u de transactie terugdraaien/opnieuw starten of vastleggen/herstarten. Dan kunt u doorgaan met het mislukken van zoveel SQL-query's op die databaseverbinding als u wilt.

  3. Vang en negeer niet de uitzondering die wordt gegenereerd wanneer een SQL-instructie mislukt. Dan stopt het programma bij de verkeerd opgemaakte zoekopdracht.

  4. Koop in plaats daarvan Oracle, Oracle genereert geen uitzondering wanneer u een query op een verbinding binnen een transactie mislukt en die verbinding blijft gebruiken.

Ter verdediging van de beslissing van PostgreSQL om de dingen op deze manier te doen... Oracle was waardoor je zacht wordt in het midden, je domme dingen laat doen en het over het hoofd ziet.



  1. 2 manieren om rijen te retourneren die alleen alfanumerieke tekens bevatten in PostgreSQL

  2. Hoe de daadwerkelijke Oracle SQL-instructie te zien die wordt uitgevoerd?

  3. Alle records verwijderen behalve de meest recente?

  4. Weeknummer van een datum halen in MS SQL Server 2005?