Hibernate抛出异常时仍自动更新实体,事务未回滚如何解决?
问题根因
- 声明式事务触发回滚的前提是异常从被
@Transactional注解修饰的方法抛出,你当前的代码在Service层方法内部用外层try-catch捕获了所有异常,直接返回了封装好的错误响应,没有抛出任何异常,Spring事务切面检测不到异常,就会正常提交事务。 - 你通过
findById查询出来的Program实体属于Hibernate的持久态对象,只要事务正常提交,你对实体属性的所有修改都会自动同步到数据库,不需要显式调用save方法,这就是为什么你没走到save代码行,数据库依然执行了update语句的原因。
解决方案
方案1:移除事务方法内部的全局异常捕获,让异常正常抛出
你可以把外层的try-catch移到Controller层处理,或者直接去掉外层try-catch,让抛出的EntityNotFoundException被事务切面捕获,自动触发事务回滚。
方案2:保留异常捕获逻辑,手动触发事务回滚
如果需要在Service层内部捕获异常并返回自定义的ApiResponse,只需要在catch块中添加手动回滚代码即可(需导入包org.springframework.transaction.interceptor.TransactionAspectSupport):
catch(Exception e) { // 手动标记事务回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); apiResponse.setError("Something went wrong while testing."); apiResponse.setStatusCode(500); return apiResponse; }
内容的提问来源于stack exchange,提问作者Raj Khot
相关产品推荐
相关产品推荐

