在多数据源场景中配置Spring事务管理器的正确方法(hibernate 5.2.6)
在将我的应用程序升级到Hibernate5.2.6(WAS5.0)和SpringCore升级到4.3.6之后,我开始出现大量臭名昭著的“无法为当前线程获得事务同步会话”hibernate异常在多数据源场景中配置Spring事务管理器的正确方法(hibernate 5.2.6),hibernate,jpa,spring-data-jpa,wildfly,transactionmanager,Hibernate,Jpa,Spring Data Jpa,Wildfly,Transactionmanager,在将我的应用程序升级到Hibernate5.2.6(WAS5.0)和SpringCore升级到4.3.6之后,我开始出现大量臭名昭著的“无法为当前线程获得事务同步会话”hibernate异常 15:13:36,907 ERROR [foo.my.CustomLdapAuthoritiesPopulator] (default task-10) Error populating authorities: javax.persistence.TransactionRequiredException:
15:13:36,907 ERROR [foo.my.CustomLdapAuthoritiesPopulator] (default task-10) Error populating authorities: javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3450)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1418)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1414)
at org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:144)
at org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95)
此应用程序使用3个数据源,在Jboss Wildfly中都配置为非XA数据源,它们是:
@Transactional(transactionManager="tmDb1")
从而生成以下完整的application-context.xml文件(hibernate属性,省略xmlns名称空间)
foo.my.framework.domain
foo.my.app.model
foo.my.app.model.db3model
我的问题是:
用一个来完成吗?我试过一些组合,但没用。如果可能,我只希望有一个事务管理器@Transactional
注释中声明tx名称@Transactional
注释上指明TM的名称- 每个数据源在Wildfly中都配置为非XA
- 我不介意使用容器事务管理器
- 所有@Service类一次只处理一个数据库。无需将事务扩展到多个数据源
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<task:annotation-driven />
<mvc:annotation-driven></mvc:annotation-driven>
<!-- Exclude controllers -->
<context:component-scan base-package="foo.my.framework, foo.my.app">
<context:exclude-filter type="regex" expression="foo\.my\.app\.web\.controllers\..*" />
</context:component-scan>
<!-- DB1 Datasource Hibernate mysql -->
<bean id="DB1" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:/myconnections/db1-datasource" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="DB1" />
<property name="packagesToScan">
<list>
<value>foo.my.framework.domain</value>
<value>foo.my.app.model</value>
</list>
</property>
</bean>
<bean id="tmDb1" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- DB2 Datasource JDBC mysql -->
<bean id="DB2" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:/myconnections/db2-datasource" />
</bean>
<bean id="tmDb2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="DB2" />
</bean>
<!-- DB3 Datasource Hibernate SQL Server JPA CriteriaBuilder -->
<bean id="DB3" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:/myconnections/db3-datasource" />
</bean>
<bean id="punDB3" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="punDB3" />
<property name="dataSource" ref="DB3" />
<property name="packagesToScan">
<list>
<value>foo.my.app.model.db3model</value>
</list>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<bean id="tmDb3" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="punDB3" />
</bean>
<tx:annotation-driven transaction-manager="tmDb1" />
<tx:annotation-driven transaction-manager="tmDb2" />
<tx:annotation-driven transaction-manager="tmDb3" />
</beans>