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:
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.
Spring supports both programmatic and declarative transaction management.
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.
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 ...
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.
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() { ... } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With