我有一个带声明式事务管理的Spring + Hibernate应用程序。
我有一项服务(FooService
),其中包含2种公开方法MethodA
和MethodB
。客户将call
MethodA
,MethodB
将调用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开始创建的事务吗?
答案 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字节码编织,事务代码将直接编入您的服务,它将正常工作。但是,如果你发现自己需要它来实现这个目的,那么你需要将你的“服务”重构为至少两个独立的对象,这是一个很好的选择,因为这是一个信号,你已经混淆了关注点和/或交叉的抽象层一节课。