Spring Data Jpa EntityManager刷新不起作用

4

我想在实体中应用外部更改,所以我在EntityManager中使用了refresh()方法, 它能在EntityManager会话中正常工作。但是对于外部更改就不起作用了。

这是基于SpringBoot 2.x的简单代码:

@ExtendWith(SpringExtension.class)
@SpringBootTest
class RewardOrderRepositoryTest {
    @Inject
    private TestRepository testRepository;

    @PersistenceContext
    private EntityManager entityManager;

    @Test
    @Transactional
    @Rollback(false)
    public void test() {
        final Test test = testRepository.findById(8L).get();
        assertThat(test.getName(), is("Tom"));
        // BREAK POINT : name modify to external mysql client(ex) mysql workbench)
        entityManager.refresh(test);
        assertThat(test.getName(), is("Alice")); // it's false, still Tom.
    }
}

为什么外部更改没有反映出来? refresh() 方法只能在 EntityManager Session 中使用吗?


顺便提一下,我已经更新了我的答案,并说明了如何显式更改隔离级别 - 你可以检查它是否按照你的预期工作。,) - Josef Cech
1个回答

2
这是由事务隔离级别引起的——MySQL默认的隔离级别是REPEATABLE READ(可重复读)

这是InnoDB的默认隔离级别。在同一事务中进行的一致性读取会读取第一次读取所建立的快照。这意味着,如果您在同一事务中发布多个普通(非锁定)SELECT语句,则这些SELECT状态也相互一致。

测试已经开始一个事务,因此它将读取相同的数据,即使这些数据已经在不同的事务中更改了。

您应该能够通过显式设置隔离级别来获得所需的行为:

@Transactional(isolation=Isolation.ISOLATION_READ_COMMITTED)

未经测试的测试方法:根据TransactionalTestExecutionListener的javadoc,测试方法似乎不支持isolation属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接