具有Spring事务的JUnit多线程测试

Nic*_*ick 5 java junit spring multithreading transactions

我正在使用配置如下的内存中H2数据库运行JUnit集成测试:

@Bean
public DataSource dataSource() {

    try {
        SimpleDriverDataSource simpleDriverDataSource = new SimpleDriverDataSource();
        simpleDriverDataSource.setDriverClass((Class<? extends Driver>) ClassUtils.forName("org.h2.Driver", this.getClass().getClassLoader()));
        simpleDriverDataSource.setUrl("jdbc:h2:file:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false;MVCC=true;FILE_LOCK=NO;mv_store=false");
        simpleDriverDataSource.setUsername("sa");
        simpleDriverDataSource.setPassword("");

        return simpleDriverDataSource;
    } catch(ClassNotFoundException e) {
        throw new IllegalStateException(e.getMessage());
    }

}
Run Code Online (Sandbox Code Playgroud)

该测试将调用服务方法。此服务方法使用执行程序服务来分叉处理。在调用服务类之前,测试方法将一些数据插入数据库,并且可以使用该服务(通过JPA存储库调用)读取这些数据,直到将任务提交给执行者服务为止。但是,运行任务时,它无法读取以前保留的数据。

如何使分支线程查看持久数据?

注意:这仅在单元测试中失败,在运行时可以正常工作。

sno*_*lli 6

假设您的测试是@Transactional,您看到的是预期的行为,因为您(通常)不希望将测试所做的更改显示给其他测试/线程,并且有可能在测试结束时回滚。

解决此问题的一种简单方法是对@Test这样的方法进行注释

@Test
@Transactional(propagation = Propagation.NEVER)
public void testYourLogics() { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

我已经能够在没有的情况下重现游览行为,propagation = Propagation.NEVER并看到它已解决。

请注意,您必须在运行测试后手动将数据库还原到干净状态,否则该测试所做的更改将对其他测试可见。