PSQLException: geçerli işlem iptal edildi, işlem bloğunun sonuna kadar komutlar yoksayıldı


152

JBoss 7.1.1 Final server.log dosyasında aşağıdaki (kesilmiş) stacktrace görüyorum:

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

at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:374)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:302)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.6.0_23]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [rt.jar:1.6.0_23]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [rt.jar:1.6.0_23]
at java.lang.reflect.Method.invoke(Method.java:597) [rt.jar:1.6.0_23]
at org.postgresql.ds.jdbc23.AbstractJdbc23PooledConnection$StatementHandler.invoke(AbstractJdbc23PooledConnection.java:455)
at $Proxy49.executeUpdate(Unknown Source)   at org.jboss.jca.adapters.jdbc.WrappedStatement.executeUpdate(WrappedStatement.java:371)
at org.infinispan.loaders.jdbc.TableManipulation.executeUpdateSql(TableManipulation.java:154) [infinispan-cachestore-jdbc-5.1.2.FINAL.jar:5.1.2.FINAL]
... 154 more

Postgres günlük dosyasının incelenmesi aşağıdaki ifadeleri gösterir:

STATEMENT:  SELECT count(*) FROM ISPN_MIXED_BINARY_TABLE_configCache
ERROR:  current transaction is aborted, commands ignored until end of transaction block
STATEMENT:  CREATE TABLE ISPN_MIXED_BINARY_TABLE_configCache(ID_COLUMN VARCHAR(255) NOT NULL, DATA_COLUMN BYTEA, TIMESTAMP_COLUMN BIGINT, PRIMARY KEY (ID_COLUMN))
ERROR:  relation "ispn_mixed_binary_table_configcache" does not exist at character 22

5.1.2.Final olan JBoss 7.1.1 Final ile birlikte gelen Infinispan'ı kullanıyorum.

İşte böyle olduğunu düşünüyorum:

  • Infinispan SELECT count(*)...herhangi bir kayıt olup olmadığını görmek için ifadeyi çalıştırmaya çalışır ISPN_MIXED_BINARY_TABLE_configCache;
  • Postgres, bir sebepten dolayı, bu ifadeyi sevmiyor.
  • Infinispan bunu görmezden gelir ve ifadeyle ilerler CREATE TABLE.
  • Postgres barfs, çünkü Infinispan'ın geri alamadığı aynı işlem olduğunu düşünüyor ve bu işlem ilk SELECT count(*)...ifadeden çıkarılıyor .

Bu hata ne anlama geliyor ve nasıl çalışılacağı hakkında bir fikir var mı?


Buraya benim gibi geldiysen yukarıdaki PSQLException: current transaction is aborted...( 25P02) ve belki de JPAya da Hibernate. Nihayet bizim (! Güzel) kaynaklandığını Logback bir ile beslenen kullanım toString(): hataya neden ve (bana göre ama accidentially farkedilmeden) güzel yutuldu -overloaded DAO nesne log.info( "bla bla: {}", obj )üretti bla bla: [FAILED toString()]. log.info( "bla bla: {}", String.valueOf( obj )bunu null-güvenli hale getirmek için değiştirmek , ancak yutmamak ve böylece ilişkisiz bir sorguda işlemi açık bırakmamak.
Andreas Dietrich

Aynı tür bir hata alıyordum. Bağlantıyı sql'den önce serbest bırakmak zorunda kaldım. Mayın kodu connection.commit ()
md idi. ariful ahsan

Yanıtlar:


203

Java ve postgresql kullanarak bir tablo üzerinde bir ekleme yaparak bu hatayı aldım. Bu hatayı nasıl yeniden oluşturabileceğinizi göstereceğim:

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

Özet:

Bu hatayı almanızın nedeni, bir işlem girmiş olmanız ve SQL Sorgularınızdan birinin başarısız olması ve bu hatayı azaltmanız ve yok saymanızdır. Ancak bu yeterli değildi, o zaman aynı bağlantıyı kullandınız, aynı sorguyu çalıştırmak için AYNI İŞLEM kullanarak. Ek iş yapmak için bozuk bir işlem kullandığınız için istisna doğru şekilde oluşturulmuş ikinci sorgunun üzerine atılır. Postgresql varsayılan olarak bunu yapmanızı engeller.

Kullanıyorum: 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".

Postgresql sürücüm: postgresql-9.2-1000.jdbc4.jar

Java sürümünü kullanma: Java 1.7

İşte İstisnayı göstermek için tablo oluşturma ifadesi:

CREATE TABLE moobar
(
    myval   INT
);

Java programı hataya neden olur:

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

}

Yukarıdaki kod bu çıktıyı benim için üretir:

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

Geçici Çözümler:

Birkaç seçeneğiniz var:

  1. En basit çözüm: Bir işlemde bulunmayın. Set connection.setAutoCommit(false);için connection.setAutoCommit(true);. Çünkü başarısız SQL başarısız sql deyimi olarak göz ardı edilir çünkü çalışır. İstediğiniz tüm sql ifadeleri başarısız olabilir ve postgresql sizi durdurmaz.

  2. Bir işlemde kalmaya devam edin, ancak ilk sql'ın başarısız olduğunu algıladığınızda, işlemi geri alma / yeniden başlatma veya işlemi tamamlama / yeniden başlatma. Sonra bu veritabanı bağlantısında istediğiniz kadar sql sorgusu başarısız olmaya devam edebilirsiniz.

  3. Bir sql deyimi başarısız olduğunda atılan özel durumu yakalayıp yoksaymayın. Ardından program hatalı biçimlendirilmiş sorguda duracaktır.

  4. Bunun yerine Oracle'ı alın, işlemdeki bir bağlantıda bir sorguda başarısız olduğunuzda ve bu bağlantıyı kullanmaya devam ettiğinizde Oracle bir istisna atmaz.

Postgresql'in işleri bu şekilde yapma kararının savunmasında ... Oracle , sizi aptalca şeyler yapmanıza ve gözden kaçırmanıza izin verecek şekilde ortada yumuşak hale getiriyordu.


10
Lol @ Option 4 ... Oracle'da biraz geliştirme yapmıştım ve son zamanlarda Postgres kullanmaya başladım ... Postgres'in bunu yapması gerçekten can sıkıcı ve şimdi programımızın büyük bir kısmını gerçekten yeniden yazmamız gerekiyor Oracle'dan Postgres'e taşınıyor. Neden Oracle gibi davranmasını sağlayan ancak otomatik taahhüt olmadan ilk seçenek gibi bir seçenek yok ?
ADTC

2
Bazı denemelerden sonra, Seçenek 2'nin Oracle davranışına en yakın seçenek olduğunu öğrendim . Birden fazla güncelleme yayınlamanız gerekiyorsa ve bir hata sonraki güncellemeleri durdurmazsa rollback(), Connectionne zaman SQLExceptionyakalandığını arayın . [ Her neyse , bunun PostgreSQL'i kullanıcıyı her şeyi açık yapmaya zorlama felsefesi ile aynı doğrultuda olduğunu fark ettim, oysa Oracle'ın birçok şeye dolaylı olarak bakma felsefesi var.]
ADTC

2
Seçenek 2 imkansız dal içeriyor or commit/restart the transaction. Gördüğüm gibi istisnadan sonra iş yapmanın bir yolu yok. rollback
Taahhüt

1
@Turbanoff tarafından ortaya çıkan sorunu doğrulayabilirim. Bu doğrudan ile de çoğaltılabilir psql. (1) bir işlem başlatın, (2) bazı geçerli ifadeler yayınlayın, (3) geçersiz bir beyan verin, (4) taahhüt -> psql taahhüt etmek yerine geri dönecektir.
Alphaaa

1
postgresql.org/message-id/op.ur57x9ue33x80h%40insanity.lain.pl bu konuyla ilgili ilginç bir tartışma. Bu sorun bir kısıtlama ihlali nedeniyle tetiklenirse, PostgreSQL geliştiricileri önceden bir çakışma olup olmadığını kontrol etmenizi (güncelleme / ekleme işleminden önceki sorgu) veya güncelleme / ekleme savepointsişleminden önceki noktaya geri dönmek için kullanmanızı önerir . Örnek kod için stackoverflow.com/a/28640557/14731 adresine bakın .
Gili

27

Oluşan ifadeden önce çıktıyı kontrol edin current transaction is aborted. Bu genellikle veritabanının kodunuzun yok sayıldığı bir istisna oluşturduğu ve şimdi sonraki sorguların bazı verileri döndürmesini beklediği anlamına gelir.

Böylece, uygulamanız arasında işlerin iyi olduğunu düşünen bir durum uyuşmazlığı ve veritabanınız arasında işleminizi en baştan geri almanızı ve yeniden başlatmanızı gerektiren bir durum uyuşmazlığı var.

Bu gibi durumlarda tüm istisnaları ve geri alma işlemlerini yakalamanız gerekir.

İşte benzer bir sorun.


Bu harika, ancak bu durumda 3. parti bir kütüphane olan ve Postgres ile konuşmayı yapan Infinispan, kodumu değil.
Jimidy

Durum hala aynı - işlem geri alınmalı. Belki de kullandığınız kütüphanenin daha yeni bir sürümü olup olmadığını kontrol edin veya sorunu hata izleyicilerinde yükseltin. SQLSoruna neden olanı tam olarak bulursanız, PostgreSQL genişletilebilirliğini kullanarak sorunu ortadan kaldıracak bir alanınız olacaktır.
vyegorov

Şüphelerimi doğruladınız gibi görünüyor - şimdi Infinispan 5.1.2 kaynağına bakacağım.
Jimidy

Adil olmak gerekirse, TableManipulation sınıfında select count (*) çalıştırma girişimi etrafında bir try-catch vardır ... Belki de Postgres sürücüsü beklenen istisnalardan birini atmıyor. Daha fazla bilgi edinmek için JBoss'a bir hata ayıklayıcı bağlayacağım.
Jimidy

Söz konusu Infinispan kodu bu hatada önerildi: problems.jboss.org/browse/… Canlı bir JBoss 7.1.1 örneğinde çalışan bir hata ayıklayıcı ekledim ve Postgres doğru yerlere istisnalar atıyor. Belki de işlerini yapmayan JdbcUtil.safeClose () ifadeleridir. Infinispan ile yükseltirim.
Jimidy

13

Bence en iyi çözüm java.sql.Savepoint kullanmaktır.

SQLException atabilir sorgu yürütmeden önce, Connection.setSavepoint () yöntemini kullanın ve istisna atılacak ise, tüm işlem geri değil, sadece bu kayıt noktasına geri alma.

Örnek kod:

Connection conn = null;
Savepoint savepoint = null;
try {
    conn = getConnection();
    savepoint = conn.setSavepoint();
    //execute some query
} catch(SQLException e) {
    if(conn != null && savepoint != null) {
        conn.rollback(savepoint);
    }
} finally {
   if(conn != null) {
      try {
          conn.close();
      } catch(SQLException e) {}

   }
}

Bir şekilde yanlışlıkla düşürdüm, sadece fark ettim. Kasıtlı değildi, cevap düzenlenmedikçe geri alamam.
cerberos

Kayıt noktası yolu gerçek çözümdür. PHP, Doctrine2 ve Postgres (9.5) ortamında da benim için çalışıyor. Teşekkürler
Helvete


5

Ruby on Rails PG'de bir geçiş oluşturmuş, DB'mi taşımıştım, ancak geliştirme sunucumu yeniden başlatmayı unuttum. Sunucumu yeniden başlattım ve işe yaradı.


Benim durumum da buydu. Bunun aptalca bir şey olduğunu düşündüm, çünkü gerçekten karmaşık bir şey yapmaya çalışmadım.
Ağustos'ta

4

Bu hatanın nedeni, geçerli veritabanı işlemine yol açan yanlış işlem yapılmadan önce başka veritabanı bulunmasıdır (çincemi İngilizceye çevirmek için google çeviri kullanıyorum



2

Geri almanız gerekiyor. JDBC Postgres sürücüsü oldukça kötü. Ancak işleminizi korumak ve bu hatayı geri almak istiyorsanız, kayıt noktalarını kullanabilirsiniz:

try {
_stmt = connection.createStatement();
_savePoint = connection.setSavepoint("sp01");
_result = _stmt.executeUpdate(sentence) > 0;
} catch (Exception e){
 if (_savePoint!=null){
 connection.rollback(_savePoint);
}
}

Daha fazlasını buradan okuyun:

http://www.postgresql.org/docs/8.1/static/sql-savepoint.html


2

Aynı sorunu vardı ama sonra veritabanında aynı adlı bir tablo olduğunu fark etti. Sildikten sonra dosyayı içe aktarabildim.


Bu benim sorunum, benim için tablolar iki farklı şemalar arasında idi.
domates

0

Bu, PostgreSQL'in çok garip bir davranışıdır, hatta istisna açıkça yakalandığı ve görmezden geldiği için, "kullanıcıyı her şeyi açık yapmaya zorlama PostgreSQL felsefesi doğrultusunda" değildir. Yani bu savunma bile geçerli değil. Bu durumda Oracle, çok daha kullanıcı dostu ve (benim için olduğu gibi) doğru davranıyor - geliştiriciye bir seçenek bırakıyor.


0

Birimde disk alanı kalmadıysa bu gerçekleşebilir.


Bunun en yaygın nedeni olmadığını anlıyorum, ancak sorun gidermem istenen bir sunucuda durum böyleydi. Bu yüzden bunun potansiyel bir neden olarak listelenmesi gerektiğini düşünüyorum.
gregb


0

Postgres ile JDBI kullanıyorum ve aynı sorunla karşılaştım, yani önceki işlemin bir ifadesinden bazı kısıtlamaların ihlalinden sonra, sonraki ifadeler başarısız olur (ama bir süre bekledikten sonra, 20-30 saniye diyelim, sorun gider ).

Biraz araştırma yaptıktan sonra problemin JDBI'mda "elle" işlem yaptığım, yani ifadelerimi BEGIN ile çevrelediğimi buldum; ... COMMIT; ve suçlu olduğu ortaya çıktı!

JDBI v2'de sadece @Transaction ek açıklaması ekleyebilirim ve @SqlQuery veya @SqlUpdate içindeki ifadeler bir işlem olarak yürütülür ve yukarıda belirtilen sorun artık gerçekleşmez!


0

Benim durumumda dosyam bozuk olduğu için bu hatayı alıyordum. Dosyaların kayıtlarını yinelerken bana aynı hatayı veriyordu.

Gelecekte herkese yardımcı olacaktır. Bu cevabı göndermenin tek nedeni bu.


0

@TransactionalEk açıklama ile bahar kullanıyorum ve istisnayı yakaladım ve bazı istisnalar için 3 kez tekrar deneyeceğim.

Posgresql için, istisna olduğunda, daha fazla işlem yapmak için aynı Bağlantı'yı kullanamazsınız.

Benim durumum için, DatasourceUtilsgeçerli bağlantıyı almak ve connection.rollback()manuel olarak aramak için kullanın . Ve yöntemi yeniden denemek için işe alma çağrısı.


0

Spring boot jpa ile çalışıyordum ve @EnableTransactionManagement uygulayarak düzeltildi

Ekli dosya size yardımcı olabilir.resim açıklamasını buraya girin


0

Spring boot jpa ile çalışıyordum ve @EnableTransactionManagement uygulayarak düzeltildi

Ekli dosya size yardımcı olabilir.


0

Bunu dene COMMIT;

Bunu pgadmin4'te çalıştırıyorum. Yardımcı olabilir. Bir önceki komutun zamanından önce durmasıyla ilgili


-1

Yalıtım seviyesini tekrarlanabilir okumadan okunan okumaya değiştirin.


-1

Conn.setAutoCommit (false) öğesini conn.setAutoCommit (true) olarak ayarlayın

Yenisini başlatmadan önce işlemleri yapın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.