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

Spring Boot中READ_UNCOMMITTED事务隔离级别不生效问题排查

问题原因及解决方案

核心问题:Hibernate延迟Flush导致修改未同步到数据库

你遇到的问题本质是Hibernate的默认Flush行为:在bookTicket1中调用saveAll()后,Hibernate并不会立即将修改同步到数据库,而是将变更暂存在一级缓存中,直到事务提交前(或触发特定Flush条件时)才执行UPDATE语句。此时数据库中的数据仍为AVAILABLE,所以即使bookTicket2使用READ_UNCOMMITTED隔离级别,也读不到未提交的LOCKED状态。

具体验证与修复步骤

1. 手动触发Flush同步修改到数据库

在bookTicket1的saveAll()之后,调用Repository的flush()方法,强制Hibernate立即将缓存中的变更写入数据库:

showSeatRepository.saveAll(showSeats);
// 新增手动flush,强制同步到数据库
showSeatRepository.flush();
System.out.println("Show Seats LOCKED. Not Committed yet.");

此时,即使事务未提交,数据库中已经存在未提交的UPDATE记录,bookTicket2的READ_UNCOMMITTED事务就能读到脏数据。

2. 确认数据库引擎支持事务与READ_UNCOMMITTED

确保你使用的数据库引擎支持事务和READ_UNCOMMITTED隔离级别:

  • 若使用MySQL,需确认表的引擎为InnoDB(MyISAM不支持事务,隔离级别设置无效)。
  • 可通过SQL查询当前数据库的全局隔离级别:
    SELECT @@GLOBAL.tx_isolation;
    
    Spring的@Transactional(isolation = Isolation.READ_UNCOMMITTED)会覆盖全局设置,但需确保数据库本身支持该级别。

3. 验证Spring事务配置生效

确认Spring的事务管理器(如JpaTransactionManager)已正确配置,@Transactional注解能正常生效:

  • 检查启动类是否添加了@EnableTransactionManagement注解(Spring Boot默认已启用,但显式添加更稳妥)。
  • 可通过日志验证事务的隔离级别是否被正确设置:在application.yml中添加日志配置,查看事务创建时的隔离级别:
    logging:
      level:
        org.springframework.transaction: DEBUG
        org.hibernate.transaction: DEBUG
    

4. 排除缓存干扰

确保bookTicket2的查询是直接从数据库读取,而非缓存:

  • Spring Data JPA的findAllByIdIn默认会执行SQL查询,不会走二级缓存(除非你显式配置了二级缓存)。
  • 若怀疑二级缓存影响,可临时禁用二级缓存,或在查询方法上添加@QueryHints(value = @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_CACHEABLE, value = "false"))。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 03:52:10