<!-- --><!-- --> <!-- -->
要求能 够 不 论 BL的方法 访问 多少个 DAO,一旦失 败 都能 够 回 滚 。
解决方案:在 S2DAO 例子程序基础上实现事务管理( JDBC 中的事务管理,出错时进行回滚)
核心问题:只使用一个 container (该容器内不仅可以装 DAO ,比如我们前面熟知的 EmployeeDao 和 DepartmentDao ;还可以装业务逻辑,比如 HogeImpl 类的 foo 方法)
核心配置文件 HogeClient.dicon
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd"> <components> <include path="dao.dicon"/> <include path="j2ee.dicon"/> <component class="examples.dao.EmployeeDao "> <aspect>dao.interceptor</aspect> </component> <component class="examples.dao.DepartmentDao "> <aspect>dao.interceptor</aspect> </component> <component class="examples.tx.HogeImpl "> <aspect>j2ee.requiredTx </aspect> </component> </components>
测试类 HogeClient.java:
package examples.tx;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
import examples.dao.DepartmentDao;
import examples.dao.EmployeeDao;
public class HogeClient {
private static final String PATH = "examples/tx/HogeClient.dicon" ;
public static void main(String[] args) {
S2Container container = S2ContainerFactory.create ( PATH );
container.init();
HogeImpl hoge = (HogeImpl) container.getComponent(Hoge. class );
hoge.foo();
}
}
接口 Hoge.java:
package examples.tx;
public interface Hoge {
public void foo();
}
实现类 HogeImpl.java:
package examples.tx;
import examples.dao.Department;
import examples.dao.DepartmentDao;
import examples.dao.Employee;
import examples.dao.EmployeeDao;
public class HogeImpl implements Hoge {
private EmployeeDao empDao ;
private DepartmentDao deptDao ;
public void setEmpDao(EmployeeDao empDao) {
this . empDao = empDao;
}
public void setDeptDao(DepartmentDao deptDao) {
this . deptDao = deptDao;
}
public void foo () {
try {
//insert emp
Employee emp = new Employee();
emp.setEmpno( 1 );
emp.setDeptno(10);
empDao.insert(emp);
System. out .println(emp);
//insert dept
Department dept = new Department();
dept.setDeptno( 1 );
dept.setDname( "foo" );
deptDao.insert(dept);
System. out .println(dept);
} finally {
// container.destroy();
}
}
}
-》在实现类的foo方法中,有两段跟数据库打交道的操作,算是一个事务。(20090519追加)
备注:J2ee.dicon文件的配置请参考前面一篇blog
(对于requiredTx的配置原先就有,不用动它;注释掉默认的HSQL,使用PostgreSQL数据库)。
-》HSQL是一种内存数据库,PostgreSQL是实实在在的数据库。(20090519追加)
说明:这个实现综合了官网上事务的自动控制部分<!-- --><!-- --> <!-- -->http://s2container.seasar.org/2.3/ja/tx.html
和下载的s2DAO示例程序。
首先自己在原先示例程序基础上再做个例子,合并两个dao的插入操作,然后将这段逻辑放入foo方法,在配置文件中对这个业务逻辑进行事务管理,从而实现了对两个dao的insert等操作进行事务处理。
对 BL( Business Logic) 层 的事 务处 理 测试结 果:
在下面的情况下 进 行 测试 : 2个 dao的 insert方法,在一个 BL方法中先后 执 行,第一个 insert成功,第二个 insert失 败 。判断 测试结 果的方法是 查 看数据 库 表里的数据。
测试 1:当不使用事 务时 ,第一个表插入成功,第二个表插入失 败 。
测试 2:当使用事 务时 ,第一个表插入失 败 ,第二个表插入失 败 。
结论 : Dao和 BL层对 象从一个 S2Container( DIContainer)中 获 取, 对 BL对 象添加事 务 要求 。
说明:实现思路和测试说明来源于部门首席技术专家!
<!-- --><!-- -->
<!-- -->
补充:
container.init(); 执行这句时,进行才初始化工作。
会调用 setEmpDao 和 setDeptDao 方法,将从容器中拿出的 empDao 和 deptDao 对象赋值给 HogeImpl 中的两个成员变量 empDao 和 deptDao 。