Spring Data中REQUIRES_NEW事务下findById读取未提交数据问题
问题解析:Spring Data事务中save后新事务查询到未持久化记录的原因
核心原因:同类方法调用导致事务注解失效
你代码里的printDriver方法虽然标注了@Transactional(Propagation.REQUIRES_NEW),但因为它和saveDriver在同一个类中,直接调用不会经过Spring的事务代理,所以这个事务注解完全没生效——printDriver其实和saveDriver共用同一个事务上下文。
为什么能查到记录?
在saveDriver的事务里,调用driverRepository.save(driver)后,JPA会把这个Driver对象存入当前EntityManager的一级缓存(内存级别的缓存)。此时哪怕还没把数据刷到数据库,调用findById时,JPA会优先从一级缓存里找对象,不会直接查数据库,所以你能获取到这个实例。
为什么数据没持久化到数据库?
这说明saveDriver的事务最终没提交:
- 大概率是
saveDriver执行过程中抛出了未捕获的异常,导致事务回滚,缓存中的修改无法同步到数据库; - 若外层还有事务,
REQUIRES_NEW的事务是独立提交的,外层回滚不会影响它,所以这种情况可以排除。
补充:若printDriver在不同Bean中的场景
假设printDriver是另一个Spring Bean的方法,此时REQUIRES_NEW生效,但READ_COMMITTED隔离级别下新事务本应看不到未提交数据。如果仍能查到,可能是Hibernate的默认flush模式(AUTO)触发了自动刷库:saveDriver的事务在挂起前,因查询操作触发flush,修改写入数据库但未提交,不过这种场景下后续事务回滚会撤销数据库修改,最终还是看不到持久化数据。但这种情况出现概率极低,同类方法调用导致事务失效才是你遇到问题的核心。
内容的提问来源于stack exchange,提问作者İlkay Gunel
相关产品推荐
相关产品推荐

