Issue
- We have some custom modules using a common external
DataSource. - When
module Acallsmodule Bwithin a database transaction, following exception is raised:
org.springframework.transaction.IllegalTransactionStateException: Pre-bound JDBC Connection found! HibernateTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single HibernateTransactionManager for all transactions on a single DataSource, no matter whether Hibernate or JDBC access.
at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:484)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.startTransaction(AbstractPlatformTransactionManager.java:400)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.start(DefaultTransactionExecutor.java:139)
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:64)
at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:57)
at com.liferay.change.tracking.internal.aop.CTTransactionAdvice.invoke(CTTransactionAdvice.java:80)
at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:57)
at com.liferay.portal.spring.aop.AopInvocationHandler.invoke(AopInvocationHandler.java:49)
.
.
.
Environment
- DXP 7.3
Resolution
-
Liferay DXPuses a uniqueHibernateTransactionManager, which is configured based on aHibernateSessionFactoryand aLiferayDataSource. -
In this user case, there is an additional external
DataSource(different fromLiferayDataSource) shared by 'n' modules.
And every module has its own Session Factory and its own Transaction Manager, giving as a result 'n' Transaction Managers sharing a unique DataSource.
-
Analyzing the error,
HibernatedefinesConnectionHolderobject as a database connection. This connection is gotten from the uniqueDataSource(common to all the 'n' modules), so the exception is generated in thisHibernatecondition:
https://github.com/spring-projects/spring-framework/blob/v4.3.22.RELEASE/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateTransactionManager.java#L479-L489 -
The solution can be addressed with one of the following options:
-
Option 1: Each module has its own
DataSource, instead of a commonDataSource. -
Option 2: All 'n' modules have a unique
Transaction Managerand a uniqueSession Factory, using the commonDataSource. This way, transactions between modules are managed by this uniqueTransaction Manager.
-
Additional Information