上篇文章《分层架构下的纯JDBC事务控制简单解决方案》中对四层架构应用中使用纯JDBC时的事务控制进行了论述,并提供了一个简单解决方案,有些网友也应该看到:在编写业务层中的方法时,事务处理的代码框架都一样,只是把持久层的操作组合起来,针对这种情况,我使用了【模板方法】模式对它进行了再度封装。添加以下几个接口和类:
1. 事务回调接口(回调方法有返回值):TransactionCallback.java
package com.tjitcast.common;
import com.tjitcast.dao.DaoException;
/**
* 事务回调接口
* @author qiujy
*/
public interface TransactionCallback<T> {
/**
* 要在事务中回调执行的方法
* @return 所指定类型的数据
* @throws DaoException 数据访问异常
*/
T doInTransaction() throws DaoException;
}
2. 事务回调接口(回调方法没有返回值):TransactionCallbackWithoutResult.java
package com.tjitcast.common;
import com.tjitcast.dao.DaoException;
/**
* 无返回值 的事务回调接口
* @author qiujy
*/
public interface TransactionCallbackWithoutResult {
/**
* 要在事务中回调执行的方法
* @throws DaoException 数据访问异常
*/
public void doInTransaction() throws DaoException;
}
3. 在事务中执行指定回调接口方法的模板类:TransactionTemplate.java
package com.tjitcast.common;
import com.tjitcast.dao.DaoException;
/**
* 在事务中执行指定回调接口方法的模板类
* @author qiujy
*/
public class TransactionTemplate {
/**
* 在事务里执行回调接口实现类中有返回值的方法
* @param <T> 返回值类型
* @param callback 回调接口
* @return 指定类型的返回值
* @throws DaoException 数据访问异常
*/
public static <T> T execute(TransactionCallback<T> callback) throws DaoException {
T result = null;
TransactionManager tx = ConnectionFactory.getTranManager();
try{
tx.beginTransaction();
result = callback.doInTransaction();
tx.commitAndClose();
}catch (DaoException e) {
tx.rollbackAndClose();
throw e;
}
return result;
}
/**
* 在事务里执行回调接口实现类中没有返回值的方法
* @param callback 回调接口
* @throws DaoException 数据访问异常
*/
public static void execute(TransactionCallbackWithoutResult callback) throws DaoException {
TransactionManager tx = ConnectionFactory.getTranManager();
try{
tx.beginTransaction();
callback.doInTransaction();
tx.commitAndClose();
}catch (DaoException e) {
tx.rollbackAndClose();
throw e;
}
}
}
添加以上几个接口和类后,业务逻辑层ServiceFacade类的代码可以修改成如下格式:
package com.tjitcast.service;
import java.util.List;
import com.tjitcast.common.TransactionCallback;
import com.tjitcast.common.TransactionCallbackWithoutResult;
import com.tjitcast.common.TransactionTemplate;
import com.tjitcast.dao.DaoException;
import com.tjitcast.dao.DaoFactory;
import com.tjitcast.dao.DeptDao;
import com.tjitcast.dao.EmployeeDao;
import com.tjitcast.entity.Dept;
import com.tjitcast.entity.Employee;
import com.tjitcast.entity.PageModel;
/**
* 业务层门面 --> 添加事务控制
* JDBC的事务默认自动提交方式,
* @author qiujy
*/
public class ServiceFacade {
private DeptDao deptDao = DaoFactory.getInstance("deptDao", DeptDao.class);
private EmployeeDao empDao = DaoFactory.getInstance("empDao", EmployeeDao.class);
/**
* 新增部门
* @param dept
*/
public void insertDept(final Dept dept){
TransactionTemplate.execute(new TransactionCallbackWithoutResult() {
public void doInTransaction() throws DaoException {
deptDao.insert(dept);
}
});
}
public void insertEmp(final Employee emp){
TransactionTemplate.execute(new TransactionCallbackWithoutResult() {
public void doInTransaction() throws DaoException {
empDao.insert(emp);
}
});
}
/**
* 获取所有部门的列表
* @return
*/
public List<Dept> getDeptList(){
return TransactionTemplate.execute(new TransactionCallback<List<Dept>>() {
public List<Dept> doInTransaction() throws DaoException {
return deptDao.getDeptList();
}
});
}
/**
* 获取指定部门下的员工分页列表
* @param deptId
* @param pageNo
* @param pageSize
* @return
*/
public PageModel<Employee> getEmpListByDeptId(final int deptId, final int pageNo, final int pageSize){
return TransactionTemplate.execute(new TransactionCallback<PageModel<Employee>>() {
public PageModel<Employee> doInTransaction() throws DaoException {
return empDao.getEmpListByDeptId(deptId, pageNo, pageSize);
}
});
}
/**
* 删除指定ID的部门
* @param id
*/
public void deleteDept(final int id){
TransactionTemplate.execute(new TransactionCallbackWithoutResult() {
public void doInTransaction() throws DaoException {
empDao.deleteByDeptId(id);
deptDao.delete(id);
}
});
}
}
这样,业务层的事务处理也被透明化了,你又只需要关注业务逻辑的组合,是不是写起来更爽啦。。
不理解??那就得先去学看看GOF设计模式之模板方法;Java核心技术之匿名内部类。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/qjyong/archive/2010/04/21/5513638.aspx#1353354
分享到:
相关推荐
内容概要:本文详细介绍了LabVIEW控件的设计与实现,尤其是一些由经验丰富的老工程师精心打造的控件。LabVIEW是一款图形化编程语言,广泛应用于数据采集、仪器控制和工业自动化领域。文中通过具体实例展示了如何利用LabVIEW创建美观且功能强大的控件,如滑动条、波形图、金属质感旋钮、动态波形图表以及智能选项卡等。作者强调了LabVIEW控件在灵活性和美观度方面的优势,并分享了许多实用的技术细节和优化方法。 适合人群:具有一定编程基础并希望深入了解LabVIEW控件设计的开发者和技术爱好者。 使用场景及目标:适用于需要进行高效的数据展示和交互设计的应用场景,如工业控制系统、实验室设备操作界面等。目标是帮助用户掌握LabVIEW控件的高级特性,提高开发效率和用户体验。 其他说明:文章不仅提供了具体的代码示例,还探讨了控件美学背后的设计理念和技术实现,鼓励读者探索更多可能性。
Delphi 12.3控件之unidac_10.4.0_d27pro.exe
11.盛趣自闭面(还是自己太菜).txt
58面经面试过程和题目.txt
电大操作系统课后习题解答
人工智能技术与应用演讲【61页PPT】
chromedriver-mac-arm64-135.0.7049.41.zip
内容概要:本文详细介绍了QPSK(四相移键控)调制方法及其在瑞利信道和高斯白噪声信道下的误码率(BER)性能分析。首先展示了QPSK星座图的绘制方法,接着构建了一个简化的QPSK发射机模型,用于将二进制比特流映射到相应的星座点。随后,分别实现了两种信道模型:高斯白噪声信道(AWGN)和瑞利信道,并解释了它们的工作原理以及如何向传输信号添加噪声。文中还提供了详细的误码率测试脚本,通过大量随机比特进行仿真,最终得到了不同信噪比条件下的误码率曲线。此外,作者还讨论了QPSK与其他调制方式如BPSK、16QAM之间的性能差异,强调了频谱效率与抗噪能力之间的权衡关系。 适合人群:对无线通信系统感兴趣的科研人员、研究生以及从事通信工程领域的工程师。 使用场景及目标:①帮助读者理解QPSK的基本原理及其在不同信道环境中的行为特性;②提供实用的Python代码片段,便于快速搭建仿真环境并验证理论结果;③探讨各种调制方式的选择依据,指导实际应用中的优化决策。 其他说明:文中多次提到‘骚操作’,意指一些巧妙但非传统的编程技巧,有助于提高代码执行效率或简化复杂度。同时提醒读者注意仿真过程中可能出现的问题,如
新建 Microsoft Word 文档 (9).docx
计算机科学与技术- 软件开发工具 培训资料
bitcount统计每个元素中设置的位数 B = bitcount(A) Counts the number '1' bits in each element B = bitcount(A, bitValue) "bitValue" = 1 = default = counts the occurance of '1' if bitValue = 0; counts the number '0' The total bits to verify is [8,16,32,or 64] based on the maximal value of A B = bitcount(A, bitValue, maxBits) the total # of bits to examine
MOM生产运营管理平台解决方案【35页PPT】
deli-数码录音电话机-HCD6238(28)P-TSD-使用说明书
Java项目基于ssm框架的课程设计,包含LW+ppt
Delphi 12.3控件之Tsilang 7.5.0.0 D12.7z
ios+UIButton分类+UIButton+UIButton图片文字位置
项目已获导师指导并通过的高分毕业设计项目,可作为课程设计和期末大作业,下载即用无需修改,项目完整确保可以运行。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载
Java项目基于ssm框架的课程设计,包含LW+ppt
Delphi 12.3控件之TextEditorPro64.7z
尝试给OpenHarmony4.0增加可以在动态库中使用的日志模块 文章使用的资源,防止gitee资源丢失