关于jdbc事务自动提交

来源:互联网 发布:音乐节拍器软件 编辑:程序博客网 时间:2024/06/11 00:31

实现jdbc事务流程:

  1. 建立数据库连接;
  2. 将autoCommit设置为false;
  3. 执行sql语句;
  4. 提交;
  5. 处理异常,如果sql语句执行失败则执行rollBack;

其中,如果执行sql语句过程中抛出异常,不调用commit,提交不会发生,但如果最后执行setAutoCommit(true),提交还是有可能发生。rollback必须显式调用,即便发生异常,执行到setAutoCommit(true)时,提交会自动进行,事务可能执行一一部分。
典型示例如下:

import java.sql.*;public class TestTranslation {    public static void main(String args[])    {        Statement stmt=null;        Connection conn=null;        try{            Class.forName("com.mysql.jdbc.Driver");            conn=DriverManager.getConnection("jdbc:mysql://localhost/javatest?user=cheng&password=***");            conn.setAutoCommit(false);            String sqlLine1="update tbl_currency set currency=currency-200,last_modified=current_timestamp WHERE account='A' and currency>=200";                st=conn.createStatement();                int r1=st.executeUpdate(sqlLine1);                String sqlLine2="update tbl_currency set currency=currency+200,last_modified=current_timestamp WHERE account='B'";                int r2=st.executeUpdate(sqlLine2);                if(r1==1&&r2==1){                    conn.commit();                    System.out.println("A2B转账成功");                }                else{                    //conn.rollback();                    System.out.println("A2B转账失败");                }        }        catch(ClassNotFoundException e){            System.out.println("class not found");        }        catch(SQLException e){            System.out.println("SQL exception");            e.printStackTrace();        }        finally{            if(null!=conn){                try{                    conn.setAutoCommit(true);                    conn.close();                }                catch(SQLException e){                    System.out.println("close sql connection failed");                }            }            if(null!=stmt){                try{                    stmt.close();                }                catch(SQLException e){                    System.out.println("close statement failed");                }            }        }    }}

这段代码是一个银行账户问题,即将A中的钱转入200到B账户中,其中有个条件,如果A账户余额小于200则不进行转账,最后对结果进行检查。如果A账户中的钱小于200,第一条语句返回0,进入转账失败流程,但不会抛出异常,如果注释掉conn.rollBack(),当执行到finally中的conn.setAutoCommit(true)时,这两条语句还是会被commit,最终的结果就是其中尽管A中的钱不再减少,但B中的钱还是会增加,所以,在这种情形下,显式调用rollBack是必需的。
下面的代码,还是被因为调用setAutoCommit而提交。

import java.sql.*;public class TestTranslation {    /**     * @param args     */    public static void main(String args[])    {        Statement stmt=null;        Connection conn=null;        try{            Class.forName("com.mysql.jdbc.Driver");            conn=DriverManager.getConnection("jdbc:mysql://localhost/test?user=cheng");            conn.setAutoCommit(false);            stmt=conn.createStatement();            stmt.executeUpdate("insert into tbl_test values('liyi',26,'female')");            stmt.executeUpdate("insert into tbl_test values('liyi',26,'female')");            conn.commit();        }        catch(ClassNotFoundException e){            System.out.println("class not found");        }        catch(SQLException e){            try {                conn.rollback();//如果这里没有rollback,执行到finally中的setAutoCommit时,执行成功的前一句依然会被提交            } catch (SQLException e1) {                e1.printStackTrace();            }            System.out.println("SQL exception");            e.printStackTrace();        }        finally{            if(null!=conn){                try{                    conn.setAutoCommit(true);                    conn.close();                }                catch(SQLException e){                    System.out.println("close sql connection failed");                }            }            if(null!=stmt){                try{                    stmt.close();                }                catch(SQLException e){                    System.out.println("close statement failed");                }            }        }    }}

其中名字是主键,第二句在第一句执行后显然应该失败,抛出异常,如果异常处理中没有rollback,执行到finally中的setAutoCommit时还是会提交第一句。
所以,尽管有异常,如果不显式调用rollback,事务还是可能执行一部分。

0 0
原创粉丝点击