2013-03-07 314 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驅動程序項目來提交錯誤報告。

相關問題