问题
I have two transactional methods one inside other. When around aspect is not set around methodA Transactional anotation work well. After calling methodA we call methodB, methodB write something in DB, then we return in methodA, throw an exception and then methodB roolback. But when I put my aspect around methodA, methodB wont rollback. I cant figure out what is happening there. I tried many combination of propagation attributes but none seems to work. Thanks in advance. I use Spring 2.5.4
I have this configuration in applicationContext.xml :
<!-- Aspect -->
<bean id="logAspect" class="LoggingAspect" />
<aop:config>
<aop:aspect id="aspectLoggging" ref="logAspect" >
<aop:pointcut id="testAround" expression="execution(* methodA(..))" />
<!-- @Around -->
<aop:around method="logProcess" pointcut-ref="testAround" />
</aop:aspect>
</aop:config>
My LoggingAspect class is like this :
@Aspect
public class LoggingAspect {
public void logProcess(ProceedingJoinPoint joinPoint) throws Throwable {
<!-- some code before -->
try {
Object result = joinPoint.proceed();
} catch (Exception e) {
log.info(e.getMessage());
<!-- some code here -->
}
<!-- some code after -->
}
}
MethodA is like this :
@Transactional(rollbackFor=Exception.class,propagation=Propagation.REQUIRED)
public something methodA() throws Exception {
methodB();
...
throw new Exception("message ...");
...
}
MethodB is like this :
@Transactional(rollbackFor=Exception.class,propagation=Propagation.REQUIRED)
public void methodB() throws Exception {
<!-- insert something in db --<
}
回答1:
Your aspect if flawed
- You must always return Object from an around aspect
- Never catch and swallow an exception
public void logProcess(ProceedingJoinPoint joinPoint) throws Throwable { ... }
Your aspect has a void
method this should be Object
and you should always return the result of the call to proceed()
.
Next you are catching and swallowing the exception if any would occur, you should always rethrow the exception if you don't this breaks proper tx, management.
Your aspect should look more liks this.
@Aspect
public class LoggingAspect {
public Object logProcess(ProceedingJoinPoint joinPoint) throws Throwable {
<!-- some code before -->
try {
Object result = joinPoint.proceed();
<!-- some code after -->
return result;
} catch (Exception e) {
log.info(e.getMessage());
<!-- some code here -->
throw e;
}
}
}
来源:https://stackoverflow.com/questions/23755006/spring-transactional-wont-rollback-after-putting-aspect-around-method