JDBC:只有当`con.commit`没有成功时,`con.rollback()`才有效吗?

Sal*_*eek 8 java commit jdbc rollback

我是Java JDBC的新手,并开发了小型数据库应用程序.我正在学习
O'Reilly - 使用JDBC和Java第2版进行数据库编程.

con.rollback()有效果只有在con.commit没有成功?

实际上我猜con.rollback()即使con.commit()成功也会产生影响.这意味着将其用作" 撤消 "动作.

我成功con.rollback()后试着打电话con.commit(),但是我没猜到.好吧/预期呢?

这个例子来自我上面提到的那本书:

con.rollback()被注释掉了.它接近尾声con.close().尝试取消注释.成功con.rollback()后不回滚东西con.commit().

import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class UpdateLogic
{

    public static void main(String args[])
    {
        Connection con = null;

        try
        {
            String driver = "com.mysql.jdbc.Driver";
            Class.forName(driver).newInstance();
            String url = "jdbc:mysql://localhost:3306/Company";
            Statement s;
            con = DriverManager.getConnection(url, "root", "");
            con.setAutoCommit(false); // make sure auto commit is off!
            s = con.createStatement();// create the first statement
            s.executeUpdate("INSERT INTO employee VALUES ('1', 'employee 1', '22','00-1234' )");

            s.close(); // close the first statement
            s = con.createStatement(); // create the second statement
            s.executeUpdate("INSERT INTO employee VALUES ('2', 'employee 2', '21','00_4321' )");

            con.commit(); // commit the two statements
            System.out.println("Insert succeeded.");
            s.close(); // close the second statement
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex)
        {
            Logger.getLogger(UpdateLogic.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException e)
        {
            if (con != null)
            {
                try
                {
                    con.rollback();
                } // rollback on error
                catch (SQLException i)
                {
                }
            }
            e.printStackTrace();
        } finally
        {
            if (con != null)
            {
                try
                {
                  //con.rollback();
                    con.close();
                } catch (SQLException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

jta*_*orn 10

当您致电时commit(),您完成/关闭当前交易.因此,由于rollback()撤消了当前事务中的任何更改(根据javadoc),它将无效地执行任何操作.


Vis*_*l K 5

con.rollback() 只有在 con.commit 不成功时才有效吗?

YES如果你之前调用它也有效果con.commit。前提是连接的自动提交模式应该是假的,使用con.setAutoCommit(false)
您在数据库中使用DML带有con.setAutoCommit(false) 的JDBC 查询进行的任何事务都不会提交到数据库,直到con.commit()被调用。您在数据库中所做的最新提交事务充当该连接的保存点。当您调用con.rollback() 时,您在此之后完成的所有事务都将savepoint被撤消。此外,如果在调用con.commit()时发生某些异常,则意味着事务未保存在数据库中。con.rollback()catch语句中调用if是一个好习惯con.commit() 失败。

  • @jmrodrigg:正如我在我的帖子中提到的, con.rollback() 和 con.commit() 仅对 autocommit 的 false 模式显示其效果。现在,如果您以原子方式执行一组事务,并且在执行第 n(>1) 个事务时遇到一些错误。这将导致控件执行 catch 语句。如果你不调用 `con.rollback` 那么如果在你的代码的其他部分为同一个 Connection 对象提交了一个成功的事务,那么这将导致不成功的原子操作的那些成功的事务也提交,这将导致损失数据完整性 (4认同)