【问题标题】:Using multiple transaction managers with hibernate-spring integration (annotation-based)使用带有 hibernate-spring 集成的多个事务管理器(基于注释)
【发布时间】:2016-01-29 06:28:41
【问题描述】:

我正在做一个项目,它需要连接到一个 oracle 数据库并从表中读取一些数据,然后在汇总数据后将它们放入第二个 mysql 数据库中。

我需要为此项目使用事务管理器。所以我做了如下的事情:

spring-application-context.xml

<tx:annotation-driven transaction-manager="oracleTransactionManager" proxy-target-class="true"/>

<bean id="oracleTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="oracleSessionFactory"/>
    <qualifier value="oracleTransactionManager"/>
</bean>

<bean id="mysqlTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="mysqlSessionFactory"/>
    <qualifier value="mysqlTransactionManager"/>
</bean>

MysqlService.java

@Transactional
@Qualifier("mysqlTransactionManager")
public class MysqlService{
    public void saveAll(List<myEntity> myEntities) {
        List<BaseEntity> baseEntities = (List<BaseEntity>) (List<?>) myEntities; 
        myEntitiyDAO.saveAll(baseEntities);
    }
}

但问题是,当我运行此代码时,出现以下错误:

Exception in thread "Thread-3" org.hibernate.HibernateException: persist is not valid without active transaction
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:341)
at com.sun.proxy.$Proxy11.persist(Unknown Source)
at com.peykasa.sdp.messagesummerizer.datamodel.smsbox.dao.MysqlTaskMessageDAOImpl.save(MysqlTaskMessageDAOImpl.java:28)
at com.peykasa.sdp.messagesummerizer.datamodel.mysql.service.MysqlTaskMessageService.saveAll(MysqlTaskMessageService.java:35)
at com.peykasa.sdp.messagesummerizer.datamodel.mysql.service.MysqlTaskMessageService$$FastClassBySpringCGLIB$$894181ef.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:708)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
at com.peykasa.sdp.messagesummerizer.datamodel.mysql.service.MysqlTaskMessageService$$EnhancerBySpringCGLIB$$c16175a6.saveAll(<generated>)
at com.peykasa.sdp.messagesummerizer.lifecycle.DataSummarizerThread.run(DataSummarizerThread.java:66)

为什么会出现此错误,我该如何解决?

我使用过 spring 4.0.5 和 hibernate 3.6.10。

提前致谢,

【问题讨论】:

    标签: hibernate spring-annotations transactional transactionmanager


    【解决方案1】:

    事务管理器继续@Transactional 而不是@Qualifier

    @Transactional("mysqlTransactionManager")
    

    See the docs.

    编辑

    我刚刚用两个独立的事务管理器(虽然没有使用休眠)运行了一个测试,它工作正常,正如预期的那样。

    您的MySqlService 是否定义为&lt;bean/&gt;? Spring只有在管理对象实例的情况下才能启动事务。

    打开org.springframework.transaction 的 TRACE 级别日志记录以获取详细的日志记录。这是我在调用 2 个 bean 时看到的;一个使用默认的 tx 管理器;另一个使用明确的...

    09:39:37.528 TRACE [main][org.springframework.transaction.support.TransactionSynchronizationManager] Initializing transaction synchronization
    09:39:37.529 TRACE [main][org.springframework.transaction.interceptor.TransactionInterceptor] Getting transaction for [org.springframework.integration.samples.jdbc.Foo.doIt]
    09:39:37.529 TRACE [main][org.springframework.transaction.interceptor.TransactionInterceptor] Completing transaction for [org.springframework.integration.samples.jdbc.Foo.doIt]
    09:39:37.530 TRACE [main][org.springframework.transaction.support.TransactionSynchronizationManager] Clearing transaction synchronization
    09:39:40.700 TRACE [main][org.springframework.transaction.support.TransactionSynchronizationManager] Initializing transaction synchronization
    09:39:40.700 TRACE [main][org.springframework.transaction.interceptor.TransactionInterceptor] Getting transaction for [org.springframework.integration.samples.jdbc.Bar.doIt]
    09:39:40.700 TRACE [main][org.springframework.transaction.interceptor.TransactionInterceptor] Completing transaction for [org.springframework.integration.samples.jdbc.Bar.doIt]
    09:39:40.701 TRACE [main][org.springframework.transaction.support.TransactionSynchronizationManager] Clearing transaction synchronization
    

    我可以在调试器中判断每个都使用正确的 tx 管理器。

    【讨论】:

    • 是的,MySqlService 和 OracleService 都是 bean 。但是我使用了 hibernate 来处理 jdbc。我认为我使用休眠对 Spring 很重要,因为 transactionManagers 的类型与你的不同。我说的对吗?
    • 应该没什么区别;正如我所说,查看 TRACE 日志以查找问题。
    猜你喜欢
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 2023-02-16
    • 2014-06-18
    • 2011-12-24
    • 2017-02-05
    • 1970-01-01
    相关资源
    最近更新 更多