繁体   English   中英

Spring中的声明式事务管理行为异常

[英]Declarative Transaction Management in Spring behaving unpredictably

我有一个带有声明式事务管理的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开始创建的事务吗?

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

我希望事务仅从MethodB开始

这行不通。 方法A和方法B在同一代理内。

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

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

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

仅当您使用Spring编织AspectJ字节码时

为什么会这样呢?

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM