JavaEE-3-JDBC事务操作

2018-08-04  本文已影响0人  ZzzRicardo_Yue

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层:

三层包的命名方法:


三层

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

1、基本

项目结构

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:设置事务的隔离级别


设置隔离级别

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

上一篇下一篇

猜你喜欢

热点阅读