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

Hibernate在READ_COMMITTED隔离级别无法读取其他事务提交的变更

Hibernate 5测试READ_COMMITTED隔离级别不符合预期

问题重现

  • 在MySQL 8中执行会话隔离级别设置:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
  • 定义的Dummy实体类:
@Getter
@Setter
@EqualsAndHashCode
@Table
@Entity
public class Dummy {
    @Id
    @Column(name = "id", nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    private String value;

    private int countDown;
}
  • 编写的测试用例:
@Test
public void testReadCommitted() {
    doInJPA(entityManagerFactorySupplier, entityManager1 -> {
        doInJPA(entityManagerFactorySupplier, entityManager2 -> {
            Dummy victim = entityManager2.find(Dummy.class, id);
            victim.setValue("Changed by T2");

            entityManager1.clear();
            Dummy beforeT2Commit = entityManager1.find(Dummy.class, id);
            assertEquals(beforeT2Commit.getValue(), "Default");
        });
        entityManager1.clear();
        Dummy afterT2Commit = entityManager1.find(Dummy.class, id);
        // 预期读取新值,但实际仍获取旧值
        assertEquals(afterT2Commit.getValue(), "Changed by T2");
    });
}
  • 异常现象:日志显示entityManager2事务提交后触发了SELECT语句,数据库中数据已更新,但entityManager1在清理持久化上下文后仍读取旧值,且未启用二级缓存。

解决方案

需在数据库连接URL中指定隔离级别,修改持久化单元配置里的JDBC URL参数:

<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/hibernate_test?sessionVariables=transaction_isolation='READ-COMMITTED'"/>

补充说明

不同数据库的隔离级别表现存在差异,例如在READ_UNCOMMITTED级别下,MySQL会出现脏读,而PostgreSQL不会。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 04:15:18