Java事务处理

在数据库操作中,一项事务是指由一条或多条对数据库更新的sql语句所组成的一个不可分割的工作单元。只有当事务中的所有操作都正常完成了,整个事务才能被提交到数据库,如果有一项操作没有完成,就必须撤消整个事务。

例如在银行的转帐事务中,假定张三从自己的帐号上把1000元转到李四的帐号上,相关的sql语句如下:

update account set monery=monery-1000 where name='zhangsan'
update account set monery=monery+1000 where name='lisi'

这个两条语句必须作为一个完成的事务来处理。只有当两条都成功执行了,才能提交这个事务。如果有一句失败,整个事务必须撤消。

在connection类中提供了3个控制事务的方法:

(1) setAutoCommit(Boolean autoCommit):设置是否自动提交事务;
(2) commit();提交事务;
(3) rollback();撤消事务;

在jdbc api中,默认的情况为自动提交事务,也就是说,每一条对数据库的更新的sql语句代表一项事务,操作成功后,系统自动调用commit()来提交,否则将调用rollback()来撤消事务。

在jdbc api中,可以通过调用setAutoCommit(false) 来禁止自动提交事务。然后就可以把多条更新数据库的sql语句做为一个事务,在所有操作完成之后,调用commit()来进行整体提交。倘若其中一项 sql操作失败,就不会执行commit()方法,而是产生相应的sqlexception,此时就可以捕获异常代码块中调用rollback()方法撤消事务。
• 示例:
• 有这样一张名叫test_user的表:uid为1的money为0元,uid为2的money为300元,uid为3的money为800元。现在uid为3的人向uid为1的人转账,每次50元。当uid为3的人的账户中的money少于或等于700的元的时候,则停止转账。也就是说,最后的uid为1的人账户为100元,uid为3的账户700元。
事务操作的基本流程是:当达到某个条件时抛出一个异常,在这个异常处理中回滚操作。事务最大的一个特点是,要么全部执行,要么不执行。但是,对于使用JAVA来操作数据库事务来说,并没用我们想的那么简单:下面这段代码故意将某个字段写错,来检验java是如何操作数据库的事务的:

public class TransactionTest {
public static void main(String[] args) throws Exception  {
  Connection conn = ConnectionFactory.getInstance().getLocalConnection(); //换成自己的连接代码
        int money=0;
    ResultSet rt=null;
        try {
          conn.setAutoCommit(false); //修改提交方式,关闭自动提交模式
          Statement st =conn.createStatement();   
          String addMoneySql = "update test_user set money=money+50 where uid=1;";
        int flag0=  st.executeUpdate(addMoneySql);
        System.out.println(flag0);
            String reduceMoneySql = "update test_user set money=money-50 where uid=3";
      int flag1  =st.executeUpdate(reduceMoneySql);
        System.out.println(flag1);
          String queryMoneySql="select money from test_user where uid=3";
            rt=st.executeQuery(queryMoneySql);
            if(rt.next()){
              money=rt.getInt("mone");
              //这里故意将字段打错,检验java如何执行事务的,原字段为money
                System.out.println(money);
          }
            if(money<=700){
                throw new RuntimeException("3号的钱已经不够了,不要汇款了");
                //抛出一个异常,在异常处理中回滚操作
            }
            conn.commit();
        } catch (Exception e) {
          e.printStackTrace();//打印出上面抛出来的异常,否则是不会显示的。
          if(conn!=null){
                  conn.rollback();
               
          }
      }
  }
}

推荐阅读

相关推荐