You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring @Transactional搭配Hibernate报错:无活动事务时saveOrUpdate无效

Spring @Transactional 生效逻辑与失效解决方案

核心生效逻辑

Spring的@Transactional基于AOP动态代理实现:当你调用被Spring管理的Bean中标记了@Transactional的public方法时,事务切面会自动拦截本次调用,在方法执行前开启事务,方法正常执行完成后提交事务,方法抛出未捕获的回滚异常(默认是RuntimeException和Error)时自动回滚事务,全程自动处理Session获取、资源释放逻辑,不需要手动编码处理。

异常根因排查

你遇到的Calling method 'saveOrUpdate' is not valid without an active transaction异常,本质是@Transactional注解根本没有生效,Spring没有自动为你开启事务,所以调用Hibernate的API时才会提示没有活跃事务。你已经配置了SessionFactory和HibernateTransactionManager,大概率是漏掉了以下关键配置或使用姿势错误:

  • 没有开启事务注解驱动:XML配置模式下需要在配置文件中添加<tx:annotation-driven transaction-manager="txManager"/>,注解配置模式下需要在配置类上添加@EnableTransactionManagement注解,这是让@Transactional生效的核心开关,很多开发者都会遗漏这一步。
  • 导错了注解包:确认你使用的@Transactional是org.springframework.transaction.annotation.Transactional,而不是javax包下的javax.transaction.Transactional,Spring默认只会识别自己包下的事务注解。
  • 方法调用不符合代理规则:如果你是在DaoImpl类的内部方法中直接调用saveOrUpdateOne,走的是this调用而非Spring代理对象的调用,会跳过事务切面,注解自然不生效。这种情况需要把事务注解加在外部调用的入口public方法上,或者从Spring上下文中获取Dao的代理对象再调用该方法。
  • 方法不是public修饰:@Transactional仅对public方法生效,非public方法即使加了注解也不会被事务切面拦截。

手动事务代码的说明

你修改后的手动处理事务的代码能正常运行,是因为你完全绕开了Spring的事务管理机制,自己编码完成了事务开启、提交、回滚、资源释放的全流程,本质上没有用到@Transactional的能力,属于冗余实现。

你最开始写的简化版代码本身没有问题,只要修正上面提到的配置或使用问题,就能正常运行,不需要额外编写事务处理逻辑。


内容的提问来源于stack exchange,提问作者Steve Atkinson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 10:57:03