Spring @Transactional在放置方法之后不会回滚

时间:2014-05-20 08:46:58

标签: spring transactions rollback transactional aspect

我有两个交易方法,一个在另一个内。当方法周围没有设置方面A时,交易分配工作很好。调用methodA之后我们调用methodB,methodB在DB中写一些东西,然后我们返回methodA,抛出异常,然后是methodB roolback。 但是当我把方法放在方法A上时,方法B不会回滚。我无法弄清楚那里发生了什么。我尝试了许多传播属性的组合,但似乎都没有。 提前致谢。 我使用Spring 2.5.4

我在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>

我的LoggingAspect类是这样的:

@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是这样的:

@Transactional(rollbackFor=Exception.class,propagation=Propagation.REQUIRED)
public something methodA() throws Exception {
    methodB();
    ...
    throw new Exception("message ...");
    ...
}

MethodB是这样的:

@Transactional(rollbackFor=Exception.class,propagation=Propagation.REQUIRED)
public void methodB() throws Exception {
    <!-- insert something in db --<
}

1 个答案:

答案 0 :(得分:2)

你的方面是否存在缺陷

  1. 您必须始终从周围返回Object
  2. 永远不会捕获并吞下异常
  3. public void logProcess(ProceedingJoinPoint joinPoint) throws Throwable  { ... }
    

    您的方面有一个void方法,应该是Object,您应该始终将调用结果返回给proceed()

    接下来你抓住并吞下异常,如果发生任何异常,你应该总是重新抛出异常,如果你不这样做会破坏正确的tx,管理。

    你的方面应该看起来更喜欢这个。

    @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;
            }   
        }
    }