Spring中事务管理问题



Spring中事务管理问题。

spring的使用处理方式有两种:声明式事务和编程式事务;
下面说一下主要使用的声明式事务使用过程的问题,如果没有事务嵌套的话事务处理很简单,事务处理过程异常抛到切面上又切面负责回滚,如果事务处理正常则又切面负责提交即可。
事务之所以复杂是因为有嵌套事务的问题,当事务嵌套是就需要进行事务传递方面的考虑:
@Transactional(propagation = Propagation.MANDATORY)—强制的(必须有transaction)
@Transactional(propagation = Propagation.NESTED)———-内嵌的transaction
@Transactional(propagation = Propagation.NEVER)————绝不能有transaction
@Transactional(propagation = Propagation.NOT_SUPPORTED)–方法要执行,遇到的transaction挂起。
@Transactional(propagation = Propagation.REQUIRED) ————–必须的(默认的)
@Transactional(propagation = Propagation.REQUIRES_NEW)———方法要执行,遇到的transaction挂起,创建新的transaction。
@Transactional(propagation = Propagation.SUPPORTS)—————-有没有无所谓
例如下面代码:代码1:

[java] view plain copy 在CODE上查看代码片派生到我的代码片
@Transactional(rollbackFor=Exception.class)
public void execute(){
PayCenterTTaskCtl taskCtl = new PayCenterTTaskCtl();
taskCtl.setTASK_TYPE(“tt”);
taskCtl.setTASK_SEQ(“2089980123992″);
taskCtl.setTASK_STAT(TaskStatEnums.失败.getValue());
taskCtl.setS_TOT(50);
taskCtl.setF_TOT(50);
taskCtl.setUPD_TIME(new Date());
batchControlUtil.updateByTaskTypeAndSeq(taskCtl);
try{
((TestTranscation)AopContext.currentProxy()).inserTest(taskCtl);
}catch(Exception e){
System.err.println(“异常”);
}

}@Transactional(rollbackFor=Exception.class)
public void inserTest(PayCenterTTaskCtl taskCtl){
batchControlUtil.insertTTaskCtl(“tt”, “2089980123992″, 100);
}
代码2:
[java] view plain copy 在CODE上查看代码片派生到我的代码片
@Transactional(rollbackFor=Exception.class)
public void execute(){
PayCenterTTaskCtl taskCtl = new PayCenterTTaskCtl();
taskCtl.setTASK_TYPE(“tt”);
taskCtl.setTASK_SEQ(“2089980123992″);
taskCtl.setTASK_STAT(TaskStatEnums.失败.getValue());
taskCtl.setS_TOT(50);
taskCtl.setF_TOT(50);
taskCtl.setUPD_TIME(new Date());
batchControlUtil.updateByTaskTypeAndSeq(taskCtl);
try{
((TestTranscation)AopContext.currentProxy()).inserTest(taskCtl);
}catch(Exception e){
System.err.println(“异常”);
}
}

@Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW)
public void inserTest(PayCenterTTaskCtl taskCtl){
batchControlUtil.insertTTaskCtl(“tt”, “2089980123992″, 100);
}
下面解释一下两种事务的不同之处:
1、首先需要声明一下,上面的方法调用都是同一个类中的调用,为了能够使注解事务生效使用了AOP的方式进行了调用,如果是通过动态注入的话就不需要使用AOP方式了;

2、事务嵌套导致事务之间具有传递性,如果都使用默认的方式,第一个事务启动后后其他的事务都将继承此事务,导致的现象是当某个子事务处理失败后,就会将整个事务标记为失败,当处理回到父方法时就会将所有数据库操作都回滚调。

3、为了使子事务不影响父事务的执行,就需要将子事务的传播方式修改为REQUIRES_NEW