如何使用JDBC在一个事务中执行2个更新查询

时间:2016-02-21 11:01:43

标签: java mysql jdbc

我是JDBC的新手,我正在尝试更新数据库中的2个表,所以我想在1个事务中执行它,所以如果一个查询失败,另一个也应该失败。我想提供这样的行为,或者只是有机会进行回滚,如果其中一个失败。

以下是我的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 + ");");

1 个答案:

答案 0 :(得分:12)

如果要以原子方式执行多个语句,则需要使用事务。 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