Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:回滚数据库更新?_Java_Mysql_Database_Transactions - Fatal编程技术网

Java:回滚数据库更新?

Java:回滚数据库更新?,java,mysql,database,transactions,Java,Mysql,Database,Transactions,我有三种方法,它们一起将节点保存到数据库中。目前,除非所有写入都成功,否则这无法达到不提交更改的预期效果 conn.setAutoCommit(false); writeNodeTable(node, newNodeNID); writeContentTypeBoutTable(node, newNodeNID); writeTerms(node, newNodeNID); conn.commit(); 如果第二个或第三个方法中存在问题(例如抛出了未捕获

我有三种方法,它们一起将节点保存到数据库中。目前,除非所有写入都成功,否则这无法达到不提交更改的预期效果

    conn.setAutoCommit(false);
    writeNodeTable(node, newNodeNID);
    writeContentTypeBoutTable(node, newNodeNID);
    writeTerms(node, newNodeNID);
    conn.commit();
如果第二个或第三个方法中存在问题(例如抛出了未捕获的异常),我希望回滚所有更改。有什么方法可以使用事务来实现这一点吗

这是一个这样的DB写入函数:

private void writeTerms(DrupalNode node, int newNodeNID) throws SQLException {
    String sql = "INSERT INTO term_node (nid, vid, tid) VALUES (?, ?, ?)";
    PreparedStatement prep = conn.prepareStatement(sql);
    prep.setInt(1, newNodeNID);
    prep.setInt(2, newNodeNID);

    String schoolName = termHelp.schoolOfAgainst(node.get(BoutField.against));
    prep.setString(3, schoolName);

    prep.execute();

    String fencerName = termHelp.fencerOfAgainst(node.get(BoutField.against));
    prep.setString(3, fencerName);
    prep.execute();
    prep.close();
}

您可以在
Connection
界面中使用
rollback
方法。


您还必须将
setAutoCommit
设置为
false
,并调用
commit
rollback
方法(视情况而定)。

您可以在
连接
界面中使用
rollback
方法。


此外,您还必须将
setAutoCommit
设置为
false
,并调用
commit
rollback
方法。如果Upul正确,则需要实现
连接.setAutoCommit(false)
连接.rollback()
方法。对于每个事务,您可能希望尝试的一件事是拥有这种流:

Connection conn = null; // or have the connection sent in
try {
    conn = getConnection(username, password);
    conn.setAutoCommit(false);
    // do stuff with connection
    conn.commit();
} catch (SQLException sqle) {
    // handle error appropriately
    conn.rollback();
} finally {
    // cleanup
    conn.close(); // depends on when the connection was allocated
}

Upul是正确的,您需要实现
Connection.setAutoCommit(false)
Connection.rollback()
方法。对于每个事务,您可能希望尝试的一件事是拥有这种流:

Connection conn = null; // or have the connection sent in
try {
    conn = getConnection(username, password);
    conn.setAutoCommit(false);
    // do stuff with connection
    conn.commit();
} catch (SQLException sqle) {
    // handle error appropriately
    conn.rollback();
} finally {
    // cleanup
    conn.close(); // depends on when the connection was allocated
}

+1.也许你需要强调更多“承诺”的必要性。否则,即使没有“回滚”,数据库中也不会保存任何内容。除非使用相同的连接对象,否则将无法工作。但是,没有负面演员阵容。答案仍然提供了一点启示。@醋:是的,需要使用相同的连接对象(并且在三个方法中都不提交)。+1。也许你需要强调更多“承诺”的必要性。否则,即使没有“回滚”,数据库中也不会保存任何内容。除非使用相同的连接对象,否则将无法工作。但是,没有负面演员阵容。答案仍然提供了一点启示。@cause:是的,需要使用相同的连接对象(并且三个方法中的任何一个本身都不需要提交),当第二次或第三次出现异常时,您将无法再回滚。我们的想法是,在处理完所有内容之前,不要执行任何提交。我可能应该补充说,所有三个调用都应该在do stuff with connection中执行,但您仍然会说,“对于每个事务,您可能希望尝试的一件事就是拥有这种流”。这是行不通的,也许这就是我对事务的看法,但我想象一个事务在分配数据库连接时开始,在提交或回滚连接对象时结束。所以我想象所有的变化[writeTable,writeContentTypeBoutTable,writeTerms]都发生在连接第一次“创建”(取决于连接池策略)和连接提交或回滚之间。@醋,没错,这个流应该从三个方法的调用方执行,这与您在帖子中的建议类似。如果第一次得到提交,那么当第二次或第三次出现异常时,您将无法再回滚。我们的想法是在处理完所有内容之前不进行任何提交。我可能应该补充说,所有三个调用都应该在do stuff with connection中执行,但您仍然会说,“对于每个事务,您可能希望尝试的一件事就是拥有这种流”。这是行不通的,也许这就是我对事务的看法,但我想象一个事务在分配数据库连接时开始,在提交或回滚连接对象时结束。所以我想象所有的变化[writeTable,writeContentTypeBoutTable,writeTerms]都发生在连接第一次“创建”(取决于连接池策略)和连接提交或回滚之间。@醋,没错,这个流应该从三个方法的调用方执行,这与你在文章中的建议相似。这三种方法的联系来自哪里?它必须与启动事务的方法相同(通过关闭自动提交)。三种方法中的连接来自何处?它必须与您启动事务的位置相同(通过关闭自动提交)。