在本系列的上一篇文章中,我们讲到了使用TransactionManger和ConnectionHolder完成线程安全的事务管理,在本篇中,我们将在此基础上引入Template模式进行事务管理。

Template模式大家应该都很熟悉,比如Spring就提供了许多Template,像JdbcTemplate和JmsTemplate等。Template模式的基本思想是:在超类里将完成核心功能的方法声明为抽象方法,留给子类去实现,而在超类中完成一些通用操作,比如JMS的Session的建立和数据库事务的准备工作等。

在本篇文章中,我们使用一个Template类来帮助管理事务,定义TransactionTemplate类如下:

package davenkin.step4_transaction_template;

import davenkin.step3_connection_holder.TransactionManager;
import javax.sql.DataSource; public abstract class TransactionTemplate
{
private TransactionManager transactionManager; protected TransactionTemplate(DataSource dataSource)
{
transactionManager = new TransactionManager(dataSource);
} public void doJobInTransaction()
{
try
{
transactionManager.start();
doJob();
transactionManager.commit();
} catch (Exception e)
{
transactionManager.rollback();
} finally
{
transactionManager.close();
}
} protected abstract void doJob() throws Exception;
}

在TransactionTemplate类中定义一个doJobInTransaction方法,在该方法中首先使用TransactionManager开始事务,然后调用doJob方法完成业务功能,doJob方法为抽象方法,完成业务功能的子类应该实现该方法,最后,根据doJob方法执行是否成功决定commit事务或是rollback事务。

然后定义使用TransactionTemplate的TransactionTemplateBankService:

package davenkin.step4_transaction_template;

import davenkin.BankService;
import davenkin.step3_connection_holder.ConnectionHolderBankDao;
import davenkin.step3_connection_holder.ConnectionHolderInsuranceDao;
import javax.sql.DataSource; public class TransactionTemplateBankService implements BankService
{
private DataSource dataSource;
private ConnectionHolderBankDao connectionHolderBankDao;
private ConnectionHolderInsuranceDao connectionHolderInsuranceDao; public TransactionTemplateBankService(DataSource dataSource)
{
this.dataSource = dataSource;
connectionHolderBankDao = new ConnectionHolderBankDao(dataSource);
connectionHolderInsuranceDao = new ConnectionHolderInsuranceDao(dataSource);
} public void transfer(final int fromId, final int toId, final int amount)
{
new TransactionTemplate(dataSource)
{
@Override
protected void doJob() throws Exception
{
connectionHolderBankDao.withdraw(fromId, amount);
connectionHolderInsuranceDao.deposit(toId, amount);
}
}.doJobInTransaction();
}
}

在TransactionTemplateBankService的transfer方法中,我们创建了一个匿名的TtransactionTemplate类,并且实现了doJob方法,在doJob方法中调用两个DAO完成业务操作,然后调用调用TransactionTemplateBankService的doJobInTransaction方法。

由于TransactionTemplate只是对上一篇文章中事务处理的一层封装,故TransactionManager和两个DAO类都保持和上一篇中的一样,此时他们都使用SingleThreadConnectionHolder获得Connection,故事务处理成功。

在下一篇文章中,我们会讲到使用Java的动态代理来完成事务处理,这也是Spring管理事务的典型方法。

Java事务处理全解析(五)—— Template模式的更多相关文章

  1. Java事务处理全解析(一)——Java事务处理的基本问题

    Java中的事务处理有多简单?在使用EJB时,事务在我们几乎察觉不到的情况下发挥着作用:而在使用Spring时,也只需要配置一个TransactionManager,然后在需要事务的方法上加上Tran ...

  2. Java事务处理全解析(六)—— 使用动态代理(Dynamic Proxy)完成事务

    在本系列的上一篇文章中,我们讲到了使用Template模式进行事务管理,这固然是一种很好的方法,但是不那么完美的地方在于我们依然需要在service层中编写和事务处理相关的代码,即我们需要在servi ...

  3. Java事务处理全解析(四)—— 成功的案例(自己实现一个线程安全的TransactionManager)

    在本系列的上一篇文章中我们讲到,要实现在同一个事务中使用相同的Connection对象,我们可以通过传递Connection对象的方式达到共享的目的,但是这种做法是丑陋的.在本篇文章中,我们将引入另外 ...

  4. Java事务处理全解析(二)——失败的案例

    在本系列的上一篇文章中,我们讲到了Java事务处理的基本问题,并且讲到了Service层和DAO层,在本篇文章中,我们将以BankService为例学习一个事务处理失败的案例. BankService ...

  5. Java事务处理全解析(七)—— 像Spring一样使用Transactional注解(Annotation)

    在本系列的上一篇文章中,我们讲到了使用动态代理的方式完成事务处理,这种方式将service层的所有public方法都加入到事务中,这显然不是我们需要的,需要代理的只是那些需要操作数据库的方法.在本篇中 ...

  6. Java事务处理全解析(八)——分布式事务入门例子(Spring+JTA+Atomikos+Hibernate+JMS)

    在本系列先前的文章中,我们主要讲解了JDBC对本地事务的处理,本篇文章将讲到一个分布式事务的例子. 请通过以下方式下载github源代码: git clone https://github.com/d ...

  7. Java事务处理全解析(三)——丑陋的案例

    在本系列的上一篇文章中,我们看到了一个典型的事务处理失败的案例,其主要原因在于,service层和各个DAO所使用的Connection是不一样的,而JDBC中事务处理的作用对象正是Connectio ...

  8. java事务处理全解析

    http://blog.csdn.net/huilangeliuxin/article/details/43446177

  9. 《Java面试全解析》505道面试题详解

    <Java面试全解析>是我在 GitChat 发布的一门电子书,全书总共有 15 万字和 505 道 Java 面试题解析,目前来说应该是最实用和最全的 Java 面试题解析了. 我本人是 ...

随机推荐

  1. NGINX 内存池有感

    写在前面 写NGINX系列的随笔,一来总结学到的东西,二来记录下疑惑的地方,在接下来的学习过程中去解决疑惑. 也希望同样对NGINX感兴趣的朋友能够解答我的疑惑,或者共同探讨研究. 整个NGINX系列 ...

  2. Android开发--EditText的应用

    1.简介 EditText主要用于数据的输入,验证等问题.例如,账号的注册,验证等等. 2.构建 如下图所示,在Text Fields有多种类型的数据输入框,我们创建图2所示的文本框,当点击按钮时,文 ...

  3. PHP中多态,抽象类,接口,

    小例子: 需求:公司定义一个接口让我们开发功能 usb.interface.php: <?php interface USB{ public function run(); } store.cl ...

  4. 编译安装的 mysql apache 用 service mysqld start 来启动

    先我们把mysql增加到linux的系统服务中去 mysql:  代码如下 复制代码 cd /usr/local/mysql/share/mysql cp mysql.server /etc/init ...

  5. iOS开发UI篇—APP主流UI框架结构

    iOS开发UI篇—APP主流UI框架结构 一.简单示例 说明:使用APP主流UI框架结构完成简单的界面搭建 搭建页面效果:                                二.搭建过程和 ...

  6. CSS动画 防止动画结束后,回归原位

    animation-fill-mode防止动画结束后,回归原位 animation: arrowsfirst 1s; animation-timing-function: linear; animat ...

  7. net 的单元测试 初学

    1. 都要以一个方法 这样的去测试 2. 利用工具 Install-Package Moq -Version 4.0 (最高的是4.5  4.0适用于自己项目的版本)   Moq.dll 进行测试   ...

  8. this面试题

    // 考题1 /*function Fn() { console.log(this);//window } Fn(); new Fn();//Fn实例 Fn.apply(Fn); //将this指向F ...

  9. 在window上安装pandas

    之前在ubuntu上安装pandas,用的easy_install.这次在window上同样方法装遇到"unable to find vcvarsall.bat",看一些网上帖子好 ...

  10. Android使用文件存储数据

    Android上最基本的存储数据的方式即为使用文件存储数据,使用基本的Java的FileOutStream,BufferedWriter,FileInputStream和BufferedReader即 ...