Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring - Is it possible to use multiple transaction managers in the same application?

I'm new to Spring and I'm wondering if its possible to use numerous transaction managers in the same application?

I have two data access layers - one for both of the databases. I'm wondering, how do you go about using one transaction managers for one layer and different transaction manager for the other layer. I don't need to perform transactions across both databases - yet. But I do need perform transactions on each database individually. I've created an image to help outline my problem:

alt text

Here is my application context configuration:

<beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:context="http://www.springframework.org/schema/context"     xmlns:tx="http://www.springframework.org/schema/tx"     xsi:schemaLocation="http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd         http://www.springframework.org/schema/context         http://www.springframework.org/schema/context/spring-context-3.0.xsd         http://www.springframework.org/schema/tx         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">      <context:component-scan base-package="cheetah.repositories" />     <tx:annotation-driven />      <bean id="entityManagerFactory"         class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">         <property name="persistenceUnitName" value="accounts" />     </bean>      <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />      <bean id="transactionManager"         class="org.springframework.orm.jpa.JpaTransactionManager">         <property name="entityManagerFactory" ref="entityManagerFactory" />     </bean>  </beans> 

Here is an example that uses this configuration:

@Repository public class JpaAccountRepository implements AccountRepository {      @PersistenceContext(unitName = "cheetahAccounts")     private EntityManager accountManager;      @Override     @Transactional     public Account findById(long id) {          Account account = accountManager.find(Account.class, id);         return account;     } } 

So for the account repository, I want to use an entity manager factory with the persistence unit set to accounts. However, with my BusinessData Repository, I want to use an entity manager factory with a different persistence unit. Since I can only define one transaction manager bean, how can I go about using different transaction managers for the different repositories?

Thanks for any help.

like image 913
Brian DiCasa Avatar asked Dec 12 '10 18:12

Brian DiCasa


People also ask

What are the types of transaction management supported by Spring ?( More than one correct?

Spring supports both programmatic and declarative transaction management.

How does transaction management work in Spring?

Transactions and Proxies. At a high level, Spring creates proxies for all the classes annotated with @Transactional, either on the class or on any of the methods. The proxy allows the framework to inject transactional logic before and after the running method, mainly for starting and committing the transaction.

Can we use @transactional in DAO layer?

You should use @Transactional at service layer, if you want to change the domain model for client B where you have to provide the same data in a different model,you can change the domain model without impacting the DAO layer by providing a different service or by creating a interface and implementing the interface in ...

Are nested transactions supported by Spring?

Not all transaction managers support nested transactions. Spring supports this out of the box only with the JDBC DataSourceTransactionManager, which is what we'll cover.


1 Answers

Where you use a @Transactional annotation, you can specify the transaction manager to use by adding an attribute set to a bean name or qualifier. For example, if your application context defines multiple transaction managers with qualifiers:

<bean id="transactionManager1"     class="org.springframework.orm.jpa.JpaTransactionManager">     <property name="entityManagerFactory" ref="entityManagerFactory1" />     <qualifier value="account"/> </bean>  <bean id="transactionManager2"     class="org.springframework.orm.jpa.JpaTransactionManager">     <property name="entityManagerFactory" ref="entityManagerFactory2" />     <qualifier value="businessData"/> </bean> 

You can use the qualifier to specify the transaction manager to use:

public class TransactionalService {      @Transactional("account")     public void setSomethingInAccount() { ... }      @Transactional("businessData")     public void doSomethingInBusinessData() { ... } } 
like image 160
Chin Huang Avatar answered Oct 06 '22 03:10

Chin Huang