java事务处理

原创 2013年12月05日 21:28:04

有个同学给我的文档,直接发上来了,


在数据库操作中,一项事务是指由一条或多条对数据库更新的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(); 
                 
           } 
       } 
   } 
}


执行这段代码。发现结果为:
 
1
1
java.sql.SQLException: Column 'mone' not found.
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:910)
at com.mysql.jdbc.ResultSet.findColumn(ResultSet.java:987)
at com.mysql.jdbc.ResultSet.getInt(ResultSet.java:2749)
at TransactionTest.main(TransactionTest.java:26)


在异常发生后,catch住异常,执行了回滚操作,查看数据库,数据库数据并没有发生变化。但是用update执行的结果来看,update是执行了的。这就说明java处理数据库的事务的执行策略:先挨句执行(下一句的基本数据是上一句执行完毕的数据,而不是数据库真实的数据),当出现回滚时候,直接通知数据库回滚。数据库回滚以后并不会通知java,所以就会出现打印执行结果与数据库数据不一致的情况。


那么,这一段代码中money(假设字段已经修改正常)的值会是多少呢?
首先 uid 1 加50,uid 3 减50,成功执行,打印出750
然后 uid 1加 50 uid 3减 50,此时 uid 3中的money为 700(发现异常,回滚)结果数据库中的uid还是750,而打印出来的值却是 700.
再执行。发现依旧会抛出3号钱已经不够的异常。
当然,我们会思考,我们重新执行这段代码的话,java是不会从数据库中间取得数据,而是直接使用脏数据。而且关闭连接等资源,关闭eclispe都不起作用,只有重新启动数据库,才能使得java从数据库读数据。
当然了,将事务按照合理的方式编排就不会出现这种错误。比如,将select语句放在uid 3之前,就不会出错了。 。(其实对于事务操作,依旧读的是脏数据,只不过这个脏数据与实际数据一致罢了。)

版权声明:本文为博主原创文章,未经博主允许不得转载。

java事务处理全解析

最近学习java事务,看到一位前辈的系列博客不错,转载过来作为记录 转载地址:http://www.davenkin.me/post/2013-02-16/40048284001    (一)Ja...
  • huilangeliuxin
  • huilangeliuxin
  • 2015年02月03日 10:26
  • 55272

JDBC事务处理

一、JDBC事务 (1)事务是作为单个逻辑工作单元执行的一系列操作。 (2)事务维护了数据的完整性、正确语义、持久性。事务中的所有SQL语句必须被成功执行,则事务才会对数据库产生持久性的影响,...
  • u010870518
  • u010870518
  • 2014年09月20日 13:47
  • 2016

Java事务处理总结

一、什么是Java事务 事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durabil...
  • zhongxiangbo
  • zhongxiangbo
  • 2017年04月28日 08:49
  • 530

Spring的事务处理机制及JAVA异常

在java中,异常分为两种,运行时异常(也就是uncheckException)和已检查异常checkException,运行时异常包括平常遇到的各种异常,如空指针异常,数据格式异常等一系列异常,这种...
  • zhousenshan
  • zhousenshan
  • 2016年02月23日 18:56
  • 835

MySQL事务处理实现方法步骤

需求说明:  案例背景:银行的转账过程中,发生意外是在所难免。为了避免意外而造成不必要的损失,使用事务处理的方式进行处理: A账户现有余额1000元,向余额为200的B账户进行转账500元。可能由于某...
  • hello_zhou
  • hello_zhou
  • 2016年07月09日 12:39
  • 7493

spring的事务处理机制

温习spring的事务处理机制,总结如下   对于SQL事务的概念以及ACID性质,可以参见我的另一篇博文 http://kingj.iteye.com/admin/blogs/167...
  • yang_ai
  • yang_ai
  • 2016年08月07日 09:37
  • 1569

Oracle事务处理

oracle事务处理 什么是事务? 事务用于保证数据的一致性,它由一组相关的dml语句组成,该组的dml语句要么全部成功,要么全部失败。 如:网上转账就是典型的要用事务来处理,用以保证数据的一致...
  • q547550831
  • q547550831
  • 2015年11月22日 17:44
  • 10314

数据库的事务处理

事务是这样一种机制,它确保多个SQL语句被当作单个工作单 元来处理。事务具有以下的作用: 一致性:同时进行的查询和更新彼此不会发生冲突,其他 用户不会看到发生了变化但尚未提交的数据。 可恢复...
  • liutao2016
  • liutao2016
  • 2017年01月10日 17:26
  • 427

Java事务处理全解析(五)—— Template模式

在本系列的上一篇文章中,我们讲到了使用TransactionManger和ConnectionHolder完成线程安全的事务管理,在本篇中,我们将在此基础上引入Template模式进行事务管理。  ...
  • huilangeliuxin
  • huilangeliuxin
  • 2015年02月03日 10:55
  • 5636

关于mysql管理事务处理

前提:数据库引擎必须是InnoDB类型。 在mysql中,MyISAM和InnoDB是最常用的两种引擎,(其中MyISAM是默认引擎),其中 MyISAM 支持全文本搜索,但不支持事务;而 Inno...
  • baidu_30000217
  • baidu_30000217
  • 2015年12月21日 12:18
  • 1097
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java事务处理
举报原因:
原因补充:

(最多只允许输入30个字)