2011-09-02 49 views
0

我有一个声明式事务管理的Spring + Hibernate应用程序。 我有一个服务(FooService),它有2种公开方法MethodAMethodB。客户将callMethodA,而这又将拨打MethodB声明式事务管理在Spring中表现不可预知

Client -> MethodA -> MethodB 

我想交易只能从方法b起开始。 这是我的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开始创建的交易?

回答

2

客户端 - >治法 - >方法b

我希望交易从方法b只启动起

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

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

BTW:这已被问了很多次之前,这里有我的一些以前的答案:

+0

谢谢你的答案(和链接)。对不起,我不知道这些问题已经在SO上提出。 –

2

我能做到的交易是仅从MethodB开始创建?

只有你use AspectJ bytecode weaving with Spring

这是为什么?

Spring的默认AOP机制是JDK dynamic proxies,它创建一个单独的Proxy实例来实现您的服务接口。这个代理被注入到其他bean中以代替您的服务,并且所有通过它的调用都将在委派您的服务之前完成事务处理。由于您的服务对自己的调用不通过代理,因此不能或不会启动事务。使用AspectJ字节码编织,交易代码将直接编织到您的服务中,并且工作正常。但是,如果您发现自己需要这个功能,可以肯定的是,您需要将您的“服务”重构为至少两个不同的对象,因为这是一个信号,表示您已经混淆了关注点和/或交叉抽象层一个班级。