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
相关产品推荐
相关产品推荐

