Spring5.3 MVC+JPA+Hibernate5.6共存调用@Transactional方法报无事务异常怎么解决
问题排查及解决步骤
1. 优先解决多事务管理器冲突问题
你现有老Spring MVC的XML配置里大概率已经存在一个HibernateTransactionManager,加上你JavaConfig里新增的JpaTransactionManager,会导致容器中存在两个事务管理器实例。@Transactional注解默认按类型匹配事务管理器,存在多个同类型实例时会匹配失败,导致事务没有正确开启。
解决方法:
- 删掉XML中原有的
HibernateTransactionManager配置,统一使用JavaConfig中配置的JpaTransactionManager即可,JpaTransactionManager同时支持原生Hibernate API和JPA API的事务管理 - 如果需要保留两个事务管理器,需要在
@Transactional注解中明确指定使用的事务管理器Bean名:// 给JpaTransactionManager指定Bean名 @Bean("jpaTransactionManager") public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { // 原有逻辑不变 } // Service方法上指定事务管理器 @Transactional("jpaTransactionManager") public void myActualServiceMethod() { // 业务逻辑 }
2. 修正SessionFactory配置
你当前的SessionFactory配置写法有问题,正确写法直接从EntityManagerFactory unwrap即可,不需要用HibernateJpaSessionFactoryBean:
@Bean public SessionFactory sessionFactory(EntityManagerFactory entityManagerFactory) { return entityManagerFactory.unwrap(SessionFactory.class); }
你之前遇到的Could not obtain transaction-synchronized Session for current thread报错是因为事务管理器没有正确生效导致的,解决完事务管理器冲突后这个报错会自动消失。
3. 移除多余的Hibernate配置
删掉additionalProperties中手动配置的hibernate.current_session_context_class属性,Spring的JpaTransactionManager会自动处理Session上下文绑定,手动配置反而会打断Spring的事务同步逻辑。
4. 检查事务注解扫描范围
确认你标注@Transactional的Service类被Spring容器正确扫描加载:
- 如果你XML中配置了
<context:component-scan>,确认Service所在包在扫描范围内 - 避免
@Transactional标注在非public方法上,Spring事务默认只对public方法生效 - 不要在Service类内部调用自身的
@Transactional方法,内部调用会绕过AOP代理导致事务不生效
内容的提问来源于stack exchange,提问作者Genku
相关产品推荐
相关产品推荐

