PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

PSQLException:bieżąca transakcja jest przerwana, polecenia ignorowane do końca bloku transakcji

Dostałem ten błąd podczas używania Javy i PostgreSQL podczas wstawiania w tabeli. Zilustruję, jak można odtworzyć ten błąd:

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

Podsumowanie:

Powodem, dla którego otrzymujesz ten błąd, jest to, że wprowadziłeś transakcję i jedno z zapytań SQL zakończyło się niepowodzeniem, połknąłeś ten błąd i zignorowałeś go. Ale to nie wystarczyło, WTEDY użyłeś tego samego połączenia, używając TEJ SAMEJ TRANSAKCJI do uruchomienia innego zapytania. Wyjątek zostanie wyrzucony na drugie, poprawnie sformułowane zapytanie, ponieważ używasz zepsutej transakcji do wykonania dodatkowej pracy. PostgreSQL domyślnie uniemożliwia Ci to.

Używam: 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".

Mój sterownik PostgreSQL to: postgresql-9.2-1000.jdbc4.jar

Korzystając z wersji Java: Java 1.7

Oto oświadczenie dotyczące tworzenia tabeli ilustrujące wyjątek:

CREATE TABLE moobar
(
    myval   INT
);

Program Java powoduje błąd:

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

}

Powyższy kod generuje dla mnie następujące dane wyjściowe:

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

Obejścia:

Masz kilka opcji:

  1. Najprostsze rozwiązanie:nie bierz udziału w transakcji. Ustaw connection.setAutoCommit(false); do connection.setAutoCommit(true); . Działa, ponieważ wtedy nieudany kod SQL jest po prostu ignorowany jako nieudana instrukcja SQL. Możesz nie wykonywać instrukcji SQL, ile chcesz, a PostgreSQL Cię nie powstrzyma.

  2. Pozostań w transakcji, ale gdy wykryjesz, że pierwszy kod SQL nie powiódł się, wycofaj/zrestartuj lub zatwierdź/zrestartuj transakcję. Następnie możesz kontynuować niepowodzenie tylu zapytań SQL w tym połączeniu z bazą danych, ile chcesz.

  3. Nie przechwytuj i nie ignoruj ​​wyjątku, który jest generowany, gdy instrukcja SQL nie powiedzie się. Następnie program zatrzyma się na źle sformułowanym zapytaniu.

  4. Zamiast tego pobierz Oracle, Oracle nie zgłosi wyjątku, gdy nie powiedzie się zapytanie dotyczące połączenia w ramach transakcji i kontynuujesz korzystanie z tego połączenia.

W obronie decyzji PostgreSQL o zrobieniu rzeczy w ten sposób... Oracle było czyniąc cię miękkim w środku, pozwalając ci robić głupie rzeczy i przeoczyć je.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Klauzula IN z NULL lub IS NULL

  2. Gdzie warunek dla połączonego stołu w Sequelize ORM

  3. Postgres dockera z danymi początkowymi nie jest utrwalany przez zatwierdzenia

  4. Zainstaluj PL/Java 1.5.2 w PostgreSQL 11

  5. Heroku i Rails:Gem Load Error w Postgresie, jednak jest określony w GEMFILE