拦截器配置顺序影响事务正常运行,以下是可以正常运行的
order的值越大就越靠近被代理的方法;
<!-- 事务配置 -->
<tx:advice id="callcenter.databaseTxAdvice" transaction-manager="springTransactionManager">
<tx:attributes>
<tx:method name="get*" propagation="SUPPORTS"/>
<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true">
<aop:pointcut expression="execution(public * com.hy.callcenter.service.database..*.*(..))" id="pc" />
<aop:advisor pointcut-ref="pc" advice-ref="callcenter.databaseTxAdvice" order="2" />
<aop:aspect ref="aspectServiceDatabase" order="1">
<aop:around method="round" pointcut-ref="pc" />
</aop:aspect>
</aop:config>
<bean id="aspectServiceDatabase" class="com.hy.callcenter.service.database.aspect.AspectServiceDatabase"/>
以上配置代码执行过程
假如被代理的方法叫做save
aspectServiceDatabase 进入
callcenter.databaseTxAdvice 进入
save
callcenter.databaseTxAdvice 出来
aspectServiceDatabase 出来
如果order 顺序对调如下:
<!-- 事务配置 -->
<tx:advice id="callcenter.databaseTxAdvice" transaction-manager="springTransactionManager">
<tx:attributes>
<tx:method name="get*" propagation="SUPPORTS"/>
<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true">
<aop:pointcut expression="execution(public * com.hy.callcenter.service.database..*.*(..))" id="pc" />
<aop:advisor pointcut-ref="pc" advice-ref="callcenter.databaseTxAdvice" order="1" />
<aop:aspect ref="aspectServiceDatabase" order="2">
<aop:around method="round" pointcut-ref="pc" />
</aop:aspect>
</aop:config>
<bean id="aspectServiceDatabase" class="com.hy.callcenter.service.database.aspect.AspectServiceDatabase"/>
以上配置代码执行过程
假如被代理的方法叫做save
callcenter.databaseTxAdvice 进入
aspectServiceDatabase 进入
save
aspectServiceDatabase 出来
callcenter.databaseTxAdvice 出来
这样的执行顺序会导致事务不起作用
因为com.hy.callcenter.service.database.aspect.AspectServiceDatabase.round把异常吞没了,
这样外层代理callcenter.databaseTxAdvice 就感知不到异常会导致事务不起作用
public class AspectServiceDatabase {
private static SfbestLogger logger = SfbestLogger.getInstance(AspectServiceDatabase.class);
//通过异常code获取消息
@Autowired
MsgService msgService;
public Object round(final ProceedingJoinPoint pjp) throws Throwable {
Object returnVal = null;
try {
long startTime = System.currentTimeMillis();
returnVal = pjp.proceed();
long endTime = System.currentTimeMillis();
long cost = endTime - startTime;
logger.info(">>>>>>>>>>业务处理方法:" + pjp.getThis().getClass().getName() + "|" + pjp.getSignature().getName() +"【"+ cost +"】");
logger.info(">>>>>>>>>>业务处理参数:" + toString(pjp.getArgs()));
logger.info(">>>>>>>>>>业务处理时长:" + cost+"毫秒");
// logger.info(">>>>>>>>>>业务处理结果:" + returnVal);
} catch (BusinessException e) {
logger.error("系统错误", e);
logger.info("业务处理方法:" + pjp.getThis().getClass().getName() + "|" + pjp.getSignature().getName());
logger.info("业务处理参数:" + toString(pjp.getArgs()));
DataResult dto = new DataResult();
int errorCode = Integer.parseInt(e.getMessage());
dto.setCode(errorCode);
//获取异常code,并获取异常信息
dto.setMsg("".equals(msgService.getMsg(errorCode))?OrderContant.DEFAULT_MSG:msgService.getMsg(errorCode));
returnVal = dto;
logger.info(returnVal.toString());
}catch (Exception e) {
logger.error("系统错误", e);
logger.info("业务处理方法:" + pjp.getThis().getClass().getName() + "|" + pjp.getSignature().getName());
logger.info("业务处理参数:" + toString(pjp.getArgs()));
DataResult dto = new DataResult();
dto.setCode(-1);
dto.setMsg("未知错误");
returnVal = dto;
}
return returnVal;
}
private String toString(Object[] args) {
StringBuilder sb = new StringBuilder();
for(Object arg : args) {
sb.append(arg).append(",");
}
return sb.toString();
}
}