0

我有一个带有声明式事务管理的 Spring+Hibernate 应用程序。我有一个服务 ( FooService),它有 2 个公共方法MethodAMethodB. call客户端将MethodA依次调用MethodB.

Client -> MethodA -> MethodB

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

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

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

4

2 回答 2

2

我可以实现仅从 MethodB 开始创建的事务吗?

仅当您将 AspectJ 字节码编织与 Spring 一起使用时

为什么会这样?

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

于 2011-09-02T13:53:35.253 回答
2

客户端->方法A->方法B

我希望事务仅从 MethodB 开始

这是行不通的。方法 A 和方法 B 在同一个代理中。

唯一正确的做法是将方法 B 移动到不同的 Bean 中。

顺便说一句:这已经被问过很多次了,这是我以前的一些答案:

于 2011-09-02T13:51:27.057 回答