2011-09-02 71 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字節碼編織,交易代碼將直接編織到您的服務中,並且工作正常。但是,如果您發現自己需要這個功能,可以肯定的是,您需要將您的「服務」重構爲至少兩個不同的對象,因爲這是一個信號,表示您已經混淆了關注點和/或交叉抽象層一個班級。