2009-09-24 100 views
10

我有一個應用程序需要連接到多個數據庫。這是一個管理應用程序,基本上用於管理不同數據庫中的條目 - 我們不需要同時訪問多個數據庫,也不需要任何類型的分佈式事務管理。在Spring中爲不同的數據源設置事務的正確方法?

基本應用的一個區域,您可以在數據庫中創建一個小工具和應用程序的其他區域,您可以在數據庫B配置類似的小玩意

我們已經交易設置和使用只是一個完美的時候工作數據源。配置看起來像這樣:

<aop:config> 
    <aop:pointcut id="companyServicePoint" 
      expression="execution(* com.company.service.CompanyService.*(..))" /> 

    <aop:advisor advice-ref="companyServiceTxAdvice" 
     pointcut-ref="companyServicePoint"/> 
</aop:config> 

<tx:advice id="companyServiceTxAdvice" transaction-manager="txManager"> 
    <tx:attributes> 
     <!-- set propogation required on create methods, all others are read-only --> 
     <tx:method name="create*" propagation="REQUIRED"/> 
     <tx:method name="*" read-only="true" /> 
    </tx:attributes> 
</tx:advice> 

<bean id="txManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource" /> 
</bean> 

這臺內CompanyService上的任何方法,任何執行的切入點和交易的建議與要求交易的名稱以「創建」開頭的任何方法的切入點關聯。事務通知與一個綁定到數據源的TransactionManager相關聯。

添加第二個(或更多)數據源時,如何將相同的事務建議應用於其他數據源?由於AOP建議只能與一個只能與一個數據源關聯的transactionManager關聯,我是否需要設置重複的事務建議?

如果我設置重複交易的意見相同的切入點,這是不是意味着,在我的CompanyService接口的方法調用任何需要對傳播史我的數據源的所有

爲了讓我的最後一個問題更清楚些,我將聲明多個bean,它們實現CompanyService接口,並且這些bean中的每一個都將有一個單獨的CompanyDAO來訪問它們各自的DataSource。我擔心這種方法意味着當調用companyService1 bean時,將在all companyService beans/dataSources上觸發事務通知。

我該怎麼做呢?

更新:其實我已經測試了我上面談到的(將兩個顧問同切入點),並調用在CompanyService實施的任何單個實例的任何方法事實上確實創建兩個新的交易結構數據源,如期望的那樣

DEBUG company.serviceDataSourceTransactionManager - Creating new transaction with name [com.company.service.CompanyService.createCompany]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 
DEBUG company.serviceDataSourceTransactionManager - Acquired Connection [connection1 string here...] for JDBC transaction 
... 
DEBUG company.serviceDataSourceTransactionManager - Creating new transaction with name [com.company.service.CompanyService.createCompany]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 
DEBUG company.serviceDataSourceTransactionManager - Acquired Connection [connection2 string here...] for JDBC transaction 
... 
DEBUG company.serviceDataSourceTransactionManager - Rolling back JDBC transaction on Connection [connection1 string here...] 
... 
DEBUG company.serviceDataSourceTransactionManager - Rolling back JDBC transaction on Connection [connection2 string here...] 

這似乎是它會導致問題的道路,因爲無論是CompanyService實例永遠只用一個單一的數據源工作。

有沒有更好的方法來配置我想要完成的任務?

回答

3

是的,你需要重複的交易建議。請注意,在以下配置中,切入點表達式將選擇特定的CompanyService bean。

<bean id="companyService1" class="com.company.service.CompanyServiceImpl"> 
    <property name="companyDao"> 
    <bean class="com.company.service.CompanyDAO"> 
     <property name="dataSource" ref="dataSource1"/> 
    </bean> 
    </property> 
</bean> 

<aop:config> 
    <aop:pointcut 
     id="companyServicePoint1" 
     expression="bean(companyService1)"/> 
    <aop:advisor 
     advice-ref="companyServiceTxAdvice1" 
     pointcut-ref="companyServicePoint1"/> 
</aop:config> 

<tx:advice id="companyServiceTxAdvice1" transaction-manager="txManager1"> 
    <tx:attributes> 
    <!-- set propogation required on create methods, all others are read-only --> 
    <tx:method name="create*" propagation="REQUIRED"/> 
    <tx:method name="*" read-only="true"/> 
    </tx:attributes> 
</tx:advice> 

<bean 
    id="txManager1" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource1"/> 
</bean> 

要配置另一個CompanyService bean,您需要複製相同的詳細樣板。另一種劃分春季交易的方法是使用TransactionProxyFactoryBean。由於它使用父級bean定義來配置由子Bean繼承的公共屬性,因此略爲不詳細。

<bean 
    id="baseTransactionProxy" 
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" 
    abstract="true"> 
    <property name="transactionAttributes"> 
    <props> 
     <prop key="create*">PROPAGATION_REQUIRED</prop> 
     <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> 
    </props> 
    </property> 
</bean> 

<bean id="companyService1" parent="baseTransactionProxy"> 
    <property name="transactionManager" ref="txManager1"/> 
    <property name="target"> 
    <bean class="com.company.service.CompanyServiceImpl"> 
     <property name="companyDao"> 
     <bean class="com.company.service.CompanyDAO"> 
      <property name="dataSource" ref="dataSource1"/> 
     </bean> 
     </property> 
    </bean> 
    </property> 
</bean> 

<bean 
    id="txManager1" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource1"/> 
</bean> 
+0

謝謝,這很好 - 只有一個事務是在調用bean實例時創建的。沒有像在界面上聲明切入點那樣優雅的解決方案,但這是我的用例所要求的... – 2009-09-25 14:39:43

相關問題