2009-09-24 21 views
10

Birden çok veritabanına bağlanması gereken bir uygulamam var. Bu, temel olarak farklı veritabanlarındaki girişleri yönetmek için kullanılan bir yönetim uygulamasıdır - aynı anda birden fazla veritabanına erişmemize veya herhangi bir dağıtılmış işlem yönetimine ihtiyacımız yok.Farklı veri kaynakları için ilkbaharda işlemleri ayarlamanın doğru yolu?

Temelde uygulama bir alan, Veritabanı A'da gadget'lar oluşturmanıza olanak tanır ve uygulama başka bir alana

Biz zaten işlemler kurdunuz ve sadece birini kullanırken, mükemmel çalışıyor sen Veritabanı B'de benzer gadget'lar yapılandırmanızı sağlar veri kaynağı. yapılandırma böylece benziyor:

<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> 

Bu CompanyService içinde herhangi yöntemlerden herhangi çalışmasının üzerinde pointcut ayarlar ve adı "oluşturmak" ile başlayan herhangi yöntemler için işlemleri gerektirir pointcut ile işlem tavsiyesi ilişkilendirir. İşlem tavsiyesi, dataSource'a bağlı bir TransactionManager ile ilişkilidir. İkinci bir (veya daha fazla) veri kaynağı eklerken, diğer veri kaynaklarına aynı işlem önerisini nasıl uygularım? AOP tavsiyesi sadece bir dataSource ile ilişkilendirilebilen bir transactionManager ile ilişkilendirilebildiğinden, yinelenen işlem önerisi ayarlamalı mıyım?

aynı pointcut I kurulum yinelenen işlem danışma, bu benim CompanyService arayüzde yöntemlerden herhangi çağırmaları benim DataSource'ları tümkarşı propogation gerektirecektir anlamına olmayacaksa

?

Son sorumu biraz daha net hale getirmek için, CompanyService arabirimini uygulayan birden fazla fasulye bildireceğim ve bu çekirdeklerin her birinin ayrı bir Veri Kaynağı'na erişmek için ayrı bir CompanyDAO olacaktır. Bu yaklaşımın, companyService1 fasülye çağrıldığında, all şirket Hizmet fasulye/dataSources üzerinde işlem tavsiyesinin tetikleneceği anlamına geleceğinden korkuyorum.

Bunu yanlış yoldan mı yapıyorum?

Güncelleme: Aslında ben yaklaşık yukarıda aslında hem yeni işlemler ortaya çıkarmaz (aynı pointcut iki danışmanları takılarak) ve CompanyService uygulamasının bireysel örneği üzerinde herhangi bir yöntemi çağrılırken konuştuk yapılandırmayı test ettik DataSource'ları, beklendiği gibi: CompanyService örneği ya daima yalnızca bir DataSource ile çalışıyor çünkü, yolda sorunlara neden olur gibi

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...] 

Bu gibi görünüyor.

Neyi başarmak istediğimi yapılandırmanın daha iyi bir yolu var mı?

cevap

3

Evet, yinelenen bir işlem tavsiye gerekir. Aşağıdaki yapılandırmada, pointcut ifadesinin belirli bir CompanyService fasulyesini seçtiğine dikkat edin.

<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> 

Başka bir CompanyService fasulyesi yapılandırmak için, aynı ayrıntılı boilerplate'i çoğaltmanız gerekir.Spring'teki işlemleri ayırmanın bir başka yolu, TransactionProxyFactoryBean kullanır. Çocuk fasulyeleri tarafından miras alınan ortak özellikleri yapılandırmak için bir ana fasülye tanımı kullandığı için daha az ayrıntılıdır.

<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

Teşekkürler, bu iyi çalışır - fasulye örneği çalıştırıldığında yalnızca tek bir işlem oluşturulur. Arayüzde nokta kesimini bildiren bir çözüm kadar zarif değil, ama benim kullanım durumum budur. –

İlgili konular