2016-02-21 35 views
2

我是JDBC的新手,我試圖在數據庫中更新2個表,所以我想在1個事務中執行此操作,所以如果一個查詢失敗,另一個應該也失敗。我想提供這樣的行爲,或者只是有機會在其中一個失敗時進行回滾。如何使用JDBC在一個事務中執行2次更新查詢

這裏是我的2個查詢:

int i = stmt.executeUpdate("INSERT INTO product (title, price, `status`) " + 
       "VALUES (\"" + product.getTitle() + "\", " + product.getPrice() + ", " + product.getStatus().ordinal() + ");"); 
int j = stmt.executeUpdate("INSERT INTO product_categories (product_id, category_id) " + 
       "VALUES (last_insert_id(), " + categoryId + ");"); 

回答

6

如果你想原子執行多個語句,你需要使用一個交易。 JDBC連接默認爲「自動提交」模式,這意味着每個語句都在其自己的事務中執行。所以你首先需要禁用自動提交模式,使用Connection.setAutoCommit(false)

在自動提交模式被禁用的情況下,執行語句將在當前事務中執行,如果沒有當前事務,則會啓動一個語句。然後可以使用Connection.commit()提交該事務,或使用Connection.rollback()回滾該事務。

你需要做這樣的事情:

try (Connection connection = DriverManager.getConnection(...)) { 
    connection.setAutoCommit(false); 
    try (Statement stmt = connection.createStatement()) { 
     stmt.executeUpdate(<your first update>); 
     stmt.executeUpdate(<your second update>); 

     connection.commit(); 
    } catch (SQLException e) { 
     connection.rollback(); 
     throw e; 
    } 
} 

有關詳細信息,請參閱JDBC教程章Using Transactions

並請瞭解準備好的聲明。將值連接成查詢字符串是不好的,因爲如果忘記了轉義值,它可能會導致SQL注入或奇怪的錯誤。另請參閱JDBC教程章節Using Prepared Statements

+0

完美答案。希望我能做到+10。 – Andreas

+0

非常感謝你! – quento

+0

這一行「connection.setAutoCommit(false);」應該在try catch塊內 –