java JDBC:调用 rollback() 方法是否只有在调用 commit() 方法不成功时才有效?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15031866/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 18:17:13  来源:igfitidea点击:

JDBC: Does call to rollback() method have effect only if call to commit() method does not succeed?

javajdbccommitrollback

提问by Saleh Feek

I am new to Java JDBC, and developed a small database application. I am learning from O'Reilly - Database Programming with JDBC and Java 2nd Edition.

我是 Java JDBC 的新手,并开发了一个小型数据库应用程序。我正在学习O'Reilly - Database Programming with JDBC and Java 2nd Edition。

Does con.rollback()have effect only ifcon.commitdoes not succeed?

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

I expected that calling con.rollback()has its effect even if con.commit()succeeded. In other words, utilizing it as an "Undo"action.

我预计con.rollback()即使con.commit()成功调用也会产生效果。换句话说,将其用作“撤消”操作。

I tried calling con.rollback()after con.commit()succeeded, but it is not working as expected. So is it alright/expected?

成功con.rollback()后我尝试调用con.commit(),但它没有按预期工作。那么它好吗/预期?

This example is from the book I mentioned above:

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

The call to con.rollback()is commented out. It is near the end before con.close(). I tried uncommenting it and running it. However, con.rollback()doesn't roll things back after con.commit()succeeded.

对 的调用已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();
                }
            }
        }
    }
}

回答by jtahlborn

When you call commit(), you complete/close the current transaction. Thus, since rollback()undoes any changes in the current transaction (as per the javadoc), it will effectively do nothing.

当您调用 时commit(),您完成/关闭当前事务。因此,由于rollback()撤消当前事务中的任何更改(根据 javadoc),它实际上什么都不做。

回答by Vishal K

Is con.rollback() has effect only if con.commit not succeeded?

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

YESAnd It also has effect if you call it before con.commit. And prerequisite is that autocommit mode of connection should be false using con.setAutoCommit(false)
Any transaction that you make in database using DMLSQL queries using JDBC with con.setAutoCommit(false)is not commited to database until con.commit()is called. The latest commited transaction that you make in database acts as the savepointfor that connection. When you call con.rollback()all transaction that you have done after that savepointis undone. Also if some exception occurs while calling con.commit(), it means that transactions are not saved in database. It is a good practice to call con.rollback()in catchstatement if con.commit()fails.

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