首先创建一个Service接口用于测试,
package com.foo.struts.demo.dept;
import java.util.List;
public interface DeptService {
public List<Dept> list();
}
再创建一个ServiceImpl实现接口(Dao和DaoImpl是空的)
package com.foo.struts.demo.dept;
import java.util.List;
public class DeptServiceImpl implements DeptService {
private DeptDao deptDao;
public DeptDao getDeptDao() {
return deptDao;
}
public void setDeptDao(DeptDao deptDao) {
this.deptDao = deptDao;
}
@Override
public List<Dept> list() {
System.out.println(" --- DeptServiceImpl.list()核心业务代码 ---");
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
if(true) {
throw new RuntimeException(".....");
}
return null;
}
}
定义一个类,继承AbstractPlatformTransactionManager,获得AbstractPlatformTransactionManager提供的事务管理(我也不知道这么说对不对...)
package com.foo.struts.demo.dept;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionStatus;
public class MyTransactionManager extends AbstractPlatformTransactionManager {
@Override
protected Object doGetTransaction() throws TransactionException {
return this;
}
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException {
System.out.println("--- MyTransactionManager: 开启事务 ---");
}
@Override
protected void doCommit(DefaultTransactionStatus status) throws TransactionException {
System.out.println("--- MyTransactionManager: 提交事务 ---");
}
@Override
protected void doRollback(DefaultTransactionStatus status) throws TransactionException {
System.out.println("--- MyTransactionManager: 回滚事务 ---");
}
}
接下来就是去配置文件中进行配置啦
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
">
<bean id="deptDao" class="com.foo.struts.demo.dept.DeptDaoImpl"></bean>
<bean id="deptService" class="com.foo.struts.demo.dept.DeptServiceImpl">
<property name="deptDao" ref="deptDao"></property>
</bean>
<!-- 声明式事务 / 编程式事务 -->
<!-- 把之前的MyTransactionManager类配置进来 -->
<bean id="transactionManager" class="com.foo.struts.demo.dept.MyTransactionManager"></bean>
<!--在这里告诉tx用id叫做"transactionManager"进行管理 transaction-manager的默认值就是"transactionManager">
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--tx:method拦截方法中的name代表方法名称,将匹配的方法注入事务管理,可以用通配符-->
<!-- 还有参数为 timeout:"代表事务超时时间设置,单位是秒,默认为-1"-->
<!--propagation:事务传播行为-->
<!--isolation:事务隔离级别定义;默认为“DEFAULT”-->
<!--read-only:事务只读设置,默认为false,表示不是只读;-->
<!--rollback-for:表示当抛出什么异常时会回滚事务,默认为java.lang.RuntimeException (可定义多个,用","相隔)-->
<!--no-rollback-for:表示放过抛出的哪种异常,当出现此异常时不会回滚事务(可定义多个,用","相隔)-->
<tx:method name="*" no-rollback-for="java.lang.RuntimeException"/>
</tx:attributes>
</tx:advice>
<aop:config>
<!--定义一个切点表达式 (上方tx:method拦截方法是对满足此切点表达式方法的再一次筛选)-->
<aop:pointcut
expression="execution(* com.foo..*.*(..))" id="pt1" />
<!--将上方定义好的txAdvice配置进aop中-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
</aop:config>
</beans>
别忘了把Dao配置进bean工厂中供deptService使用:
<bean id="deptDao" class="com.foo.struts.demo.dept.DeptDaoImpl"></bean>
<bean id="deptService" class="com.foo.struts.demo.dept.DeptServiceImpl">
<property name="deptDao" ref="deptDao"></property>
</bean>
现在就可以去做测试了
@Test
public void test04() {
ClassPathXmlApplicationContext cxt = new ClassPathXmlApplicationContext("classpath:/application.xml");
DeptService deptService = (DeptService) cxt.getBean("deptService");
deptService.list();
//System.out.println("对象类型是:"+hello.getClass());
}
结果:
提交事务成功,测试用例中抛出的RuntimeException被配置文件中的no-rollback-for监管到所以没有进行回滚
声明事务算是写好了.. 有什么补充请不吝赐教