1

我有一个服务,它有几个标有 的方法@Transactional,包括方法 a、b 和 c。这3个方法嵌套如下:a -> b -> c。这是一个代码示例:

@Transactional
public void a() {
    while(condition) {
        try {
            b();
        } catch(MyException e) {
            logger.warn(e.getMessage());
        }
    }
}

然而,方法 b 的注释如下:

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = {MyException.class})

但是,当MyException从方法 c 抛出时,异常在方法 a 处被捕获,当该异常退出时,事务被提交,其中包括通过调用 b() 所做的任何事情,该调用引发了异常并且应该回滚(? )。我正在使用带有 spring 3.0.7 的 sql server 2012 express,我的 spring 配置是这样的:

<tx:annotation-driven />
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
    <qualifier value="txm1"/>
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
    <property name="dataSource" ref="dataSource"/>
    <property name="persistenceXmlLocation" value="classpath:META-INF/jpa-persistence.xml"/>
    <property name="persistenceUnitName" value="Unit1" />
</bean>
4

1 回答 1

2

Methodb似乎与 method 属于同一类a。如果您不使用 AspectJ,则@Transactional-annotations 由 JDK 动态代理处理,您从类外部的调用通过该代理传递到 method a。调用需要通过代理才能使@Transactional-annotations 生效,例如,请参见此处的“了解 AOP 代理”:http ://static.springsource.org/spring/docs/3.0.0.M3/spring-框架参考/html/ch08s06.html

这里要理解的关键是 Main 类的 main(..) 中的客户端代码具有对代理的引用。这意味着对该对象引用的方法调用将是对代理的调用,因此代理将能够委托给与该特定方法调用相关的所有拦截器(建议)。但是,一旦调用最终到达目标对象,在这种情况下是 SimplePojo 引用,它可能对自身进行的任何方法调用,例如 this.bar() 或 this.foo(),都将针对这个参考,而不是代理。这具有重要意义。这意味着自调用不会导致与方法调用相关的建议有机会执行。

于 2012-04-06T12:53:20.723 回答