美文网首页
JavaEE-3-JDBC事务操作

JavaEE-3-JDBC事务操作

作者: ZzzRicardo_Yue | 来源:发表于2018-08-04 11:40 被阅读0次

    1、引子

    收款人、付款人,转账的金额,要求不能出现付款人的钱被扣除而收款人没有收到钱的情况发生。


    sql事务操作
    try{
            //开启事务;
            update account set money=money-100 where name='tom';
            update account set money=money+100 where name='jerry';
            //提交事务;
    }catch(Exception e){
            //回滚事务;
    }
    

    2、使用JDBC原生API模拟转账功能

    jack转出1000块
    tom收入1000块
    这样做显然是不符合前面说的那个事务的标准的,所以我们要进行修改:
    正确的事务操作逻辑
    注意这里setAutoCommit(false)就是说执行executeUpdate不是自动提交了,是由事务来操作。

    3、使用DBUtils操作事务

    这里如果我们使用Apache自己搞的DBUtils去简化JDBC的操作的时候,我们会发现,构造的QueryRunner这个核心类有些构造方法构造出的对象是不支持事务操作的!!(因为一些构造方法传入的是连接池,在同一个事务中两个对数据库的操作使用的可能是不同的连接)
    比如:

    不支持事务的QueryRunner构造方法
    支持事务的是如下构造的:
    支持事务的QueryRunner构造方法
    为什么这个可以?因为我们在对数据库进行具体操作的时候是要手动传Connection的,我们只要传相同的即可
    正确代码如下:
    代码1
    代码2
    然后相应的加try/catch/finally块,在catch块中加conn.rollback();

    4、对上述转账操作的原理分析:三层思想

    分为3层:

    • DAO:(data access object)数据访问层,用于增删改查
    • Service:业务层,修改密码、找回密码类似的操作
    • Web层(就是View层):给用户看的


      三层示意图

    三层包的命名方法:

    • com.itheima:公司域名倒写
    • com.itheima.dao:dao层
    • com.itheima.service:service层
    • com.itheima.domain:javabean
    • com.itheima.utils:工具
    • com.itheima.web/view:web层
      具体的三层思想实现的步骤:
      【步骤一】:导入JDBC相关的jar包和工具类.
      【步骤二】:创建包结构.
      【步骤三】:编写各层的类,实现功能转账功能Test-->Service-->DAO

    三层

    上一篇文章我们学习了三层思想的基本思路,现在我们实地实践一下。

    1、基本

    项目结构
    • c3p0-0.9.1.2.jar:c3p0连接池
    • mchange-commons-java-0.2.11.jar: c3p0连接池依赖的jar包
    • commons-dbutils-1.6.jar:Apach公司自己搞的一个简化JDBC数据库操作的jar包
    • mysql-connector-java-5.1.37-bin.jar:连接数据库必备jar包

    2、DAO层(数据访问层)和Service层(业务层)

    AccountDao

    DAO直接操作数据库。


    AccountService

    位于view层和DAO层之间

    如本篇开头所示的View、Service、DAO层图示,当我们在DAO层遇到异常时,就要使劲抛,因为DAO层只处理数据库的读取工作的,其他的业务处理(异常也算是业务处理一部分)不去做;
    在Service遇到异常就要使劲解决,不能想着抛给View层,因为View层是直接接触用户的层,我们不大可能让用户来解决我们程序出现的问题

    3、View层

    View层

    4、总结

    在Service层中,有数据库链接的获取,开启事务,提交事务,回滚事务,关闭链接等操作,很显然这些和我们Service层的业务层功能有所违背.
    我们应该使用一个链接管理类,(这个类一般放到utils包中)专门负责数据库链接的获取,开启事务,提交事务,回滚事务,关闭链接,更为合适。

    除了这些之外,我们在后面要学到的Servlet,我们把Servlet类放在Servlet包中: 包结构

    之前的初级版本主要是在事务处理方面的逻辑还交给了Service层去做,这与我们业务层的逻辑不大符合,这是不对的。

    1、分离事务处理方面的逻辑

    创建ConntionManager工具类,使当前线程下的Connection对象数据共享

    ConntionManager
    上图中的Connection是存在一个叫做ThreadLocal的对象中的,在:
    https://www.jianshu.com/p/7be7f73690fd有详细介绍。
    注意这里getConnectionFromtl()的方法是关键!

    然后在AccountService中就可以删除之前直接操作事务的代码,改为由这个工具类进行操作。


    开启和提交事务 回滚和关闭连接

    Tip:设置事务的隔离级别


    设置隔离级别

    在开启事务之前,设置事务的隔离级别,具体的内容自己去网上搜

    相关文章

      网友评论

          本文标题:JavaEE-3-JDBC事务操作

          本文链接:https://www.haomeiwen.com/subject/eavpvftx.html