Spring中的声明式事务管理表现不可预测

时间:2011-09-02 13:48:44

标签: java hibernate spring transactions spring-transactions

我有一个带声明式事务管理的Spring + Hibernate应用程序。 我有一项服务(FooService),其中包含2种公开方法MethodAMethodB。客户将call MethodAMethodB将调用Client -> MethodA -> MethodB

<bean id="FooService"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager" />
    <property name="target" ref="FooServiceTarget" />
    <property name="transactionAttributes">
      <props>
        <prop key="MethodB">PROPAGATION_REQUIRED,-FooException</prop>
      </props>
   </property>
</bean>

我希望事务仅从MethodB开始。 这是我的春季应用程序上下文的片段:

MethodA

但是,当我从客户端调用MethodB时,在调用MethodA时,它不会创建事务代理。 如果我在应用程序上下文中将MethodA 添加到bean配置中,则会调用事务代理(按预期启动{{1}})。 为什么会这样?我可以实现仅从MethodB开始创建的事务吗?

2 个答案:

答案 0 :(得分:2)

  

客户 - &gt;方法A - &gt;方法b

     

我希望事务仅从MethodB开始

开始

这不起作用。方法A和方法B在同一代理中。

唯一合适的做法是将方法B移到另一个Bean中。

顺便说一下:之前已经多次询问过,这里有一些我以前的答案:

答案 1 :(得分:2)

  

我是否可以实现仅从MethodB开始创建的交易?

仅限use AspectJ bytecode weaving with Spring

  

为什么会这样?

Spring的默认AOP机制是JDK dynamic proxies,它创建了一个实现服务接口的独立代理实例。此代理将注入到其他bean中以代替您的服务,并且所有通过它的调用将在委派给您的服务之前执行事务处理。由于从您的服务到自身的呼叫不通过代理,因此不能或将要启动任何事务。使用AspectJ字节码编织,事务代码将直接编入您的服务,它将正常工作。但是,如果你发现自己需要它来实现这个目的,那么你需要将你的“服务”重构为至少两个独立的对象,这是一个很好的选择,因为这是一个信号,你已经混淆了关注点和/或交叉的抽象层一节课。