Tato chyba se mi zobrazila při použití Java a PostgreSQL při vkládání do tabulky. Ukážu vám, jak můžete tuto chybu reprodukovat:
org.postgresql.util.PSQLException: ERROR:
current transaction is aborted, commands ignored until end of transaction block
Shrnutí:
Důvodem, proč se vám zobrazí tato chyba, je to, že jste zadali transakci a jeden z vašich SQL dotazů selhal a vy jste toto selhání zhltli a ignorovali. Ale to nestačilo, PAK jste použili stejné připojení pomocí STEJNÉ TRANSAKCE ke spuštění dalšího dotazu. Výjimka se vyvolá u druhého, správně vytvořeného dotazu, protože k další práci používáte nefunkční transakci. PostgreSQL vám v tom ve výchozím nastavení brání.
Používám: 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 ovladač PostgreSQL je: postgresql-9.2-1000.jdbc4.jar
Použití verze Java: Java 1.7
Zde je příkaz vytvoření tabulky pro ilustraci výjimky:
CREATE TABLE moobar
(
myval INT
);
Program Java způsobuje chybu:
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();
}
}
Výše uvedený kód mi vytváří tento výstup:
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
Řešení:
Máte několik možností:
-
Nejjednodušší řešení:Neúčastněte se transakce. Nastavte
connection.setAutoCommit(false);
naconnection.setAutoCommit(true);
. Funguje to, protože pak je neúspěšný SQL ignorován jako neúspěšný příkaz SQL. Jste vítáni, když selžete SQL příkazy, jak chcete, a PostgreSQL vás nezastaví. -
Zůstaňte v transakci, ale když zjistíte, že první SQL selhal, transakci buď odvolejte/znovu spusťte, nebo potvrďte/restartujte transakci. Potom můžete pokračovat v selhání tolika SQL dotazů na tomto databázovém připojení, kolik chcete.
-
Nezachycujte a ignorujte výjimku, která je vyvolána, když příkaz SQL selže. Poté se program zastaví na chybně naformátovaný dotaz.
-
Získejte místo toho Oracle, Oracle nevyvolá výjimku, když selžete dotaz na připojení v rámci transakce a budete toto připojení nadále používat.
Na obranu rozhodnutí PostgreSQL dělat věci tímto způsobem... Oracle byl Díky tomu budete uprostřed měkcí, budete moci dělat hloupé věci a budete na to mít výhled.