Spring JPA实现保存或重复查询的事务异常问题求助
问题:单事务内实现「保存或查询」逻辑时的事务回滚问题
场景与代码实现
业务需求:插入实体时,若触发唯一约束重复(抛出DataIntegrityViolationException),则查询数据库中已存在的对应实体。已在数据库列上设置唯一约束及提示信息,通过判断异常信息识别重复场景。
使用Spring Boot + Spring Boot Data JPA Starter,核心逻辑代码如下:
val entity = try{ repository.save(Entity(....)) }catch(ex: DataIntegrityViolationException){ if(!indicatesDuplication(ex)) throw ex repository.findByUniqueKey(...) }
遇到的异常
采用Spring声明式事务默认配置,运行时抛出以下异常:
Caused by: org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only
问题分析与尝试的解决方案
个人分析:默认REQUIRED传播行为下,每个@Transactional方法创建的逻辑事务映射到同一物理事务。save方法的默认@Transactional未配置noRollbackFor=[DataIntegrityViolationException::class],导致逻辑事务被标记为回滚,最终引发UnexpectedRollbackException。
尝试过的解决方案:
- 在Repository接口中重写
save方法并添加@Transactional(noRollbackFor = [DataIntegrityViolationException::class])注解,但问题依旧。调试发现事务代码使用SimpleJpaRepository的方法缓存,未包含自定义的回滚规则。
更新后的调试发现
按照Spring文档建议,在Repository中声明而非重写方法以修改事务配置,仍出现回滚问题。进一步调试发现,触发回滚规则的异常并非Spring的DataAccessException体系,而是Jakarta的jakarta.persistence.PersistenceException。疑问:Spring是否应该通过异常转换将Jakarta异常转换为Spring的DataAccessException体系?
内容的提问来源于stack exchange,提问作者Barracuda
相关产品推荐
相关产品推荐

