2013-03-07 304 views
1

我有一个非常长的事务,我试图使用JDBC执行PostgreSQL。在JDBC我不能使用COMMITROLLBACK,所以我想实现在Java代码中我所期望的行为......PostgreSQL事务失败:“没有正在进行的事务”

try { 
    con = DriverManager.getConnection(url, user, password); 

    con.setAutoCommit(false); 
    Statement st = con.createStatement(); 
    st.execute(myHugeTransaction); 

    con.commit(); 
} catch (SQLException ex) { 
    try { 
     con.rollback(); 
    } catch (SQLException ex1) { 
     // log... 
    } 
    // log... 
} 

对于小的语句,这工作得很好,但对于路数有关在一个事务10K报表,失败与

org.postgresql.util.PSQLException: ERROR: kind mismatch among backends. Possible last query was: "COMMIT" kind details are: 0[C] 1[N: there is no transaction in progress] 

con.commit线有趣的是,如果我赶上SQL警告与st.getWarnings();我可以看到数据库的实际处理我发送整个脚本,就在提交时,这一切都失败了。

顺便说一句,交易是完全正常的。我将它的一个精确副本写入一个文件,并且可以通过将其复制到pgAdmin中而无误地运行它。希望你能帮助我在那一个,我一直在寻找,现在几个小时测试的东西...

编辑

也许是我没有得到这个权利,所以两个问题:

  1. 我可以在Statement.execute()的一个调用中执行多个语句吗?
  2. 如果不是,使用JDBC使用多个语句来运行脚本的正确方法是什么(无需解析并将其拆分为单个语句)?
+0

你没有做任何在你的脚本中进行提交(直接或间接)? – 2013-03-07 16:20:25

+0

此错误来自pgpool。您可能会抛出一个不受pgpool配置支持的多语句查询。 – 2013-03-07 17:09:39

+0

如果您在'Statement.execute()'调用中执行多个语句,那么您没有按照预期使用JDBC API。 – 2013-03-07 19:39:39

回答

0

老实说,如果这是一个SQL脚本,你最好还是用shell转义到psql。这是处理这个问题的最好方法。一般来说,我曾尝试解析SQL代码并将其运行在数据库中,导致出现太多令人不快的意外。这样疯狂的谎言。

你说“小脚本”,这导致我得出结论,你正在设置一个数据库(或升级一个,但这是因为没有查询的可能性)。通过Shell转义使用psql,不要回头。这真的是最好的方法。

我想,如果你有你可以尝试添加明确的BEGIN和COMMIT到你的脚本。

我不知道为什么它似乎暗中提交事务。您已正确设置自动提交。你的代码中没有明显的问题。是否有可能你有一个旧的或有问题的JDBC驱动程序?如果没有,我会推荐使用PostgreSQL JDBC驱动程序项目来提交错误报告。

相关问题