Quartz 集成测试和交易

Quartz Integration test and transactions

我尝试在 Quartz 调度程序上创建集成测试。

我有 2 个表:eventstasks。计划程序通过 cron 触发器通过 事件 创建 任务

@SneakyThrows
@Test
public void taskGenerationBeanTest() {
    RequestData request = requestBuilder(str(), str(), str()).build();
    String orderId = String.valueOf(UUID.randomUUID());
    Event event1 = getEvent("type1", request, orderId);
    Event event2 = getEvent("type2", request, orderId);

    eventRepository.save(event1);
    eventRepository.save(event2);

    Thread.sleep(20000);
    List<Event> events = eventRepository.findAll();
    Thread.sleep(1000);
    List<Task> actual = taskRepository.findAll();

    assertAll(
            () -> assertEquals(2, actual.size()),
            () -> assertTrue(actual.stream().anyMatch(t ->
                    "type1".equals(t.getEvent().getEventType()))),
            () -> assertEquals(event1.getOrderId(), actual.get(0).getEvent().getOrderId())
    );
}

首先,我得到异常:

could not initialize proxy - no Session

我使用这个答案 并添加 spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true 到我的测试配置。 所以现在我遇到了另一个问题 - 我的测试有时是正确的,但更多时候它失败了,因为它只创建 1 task.

方法,由Quartz执行:

@Override
@Transactional(isolation = Isolation.REPEATABLE_READ)
public int createAndSaveTasks(EventType eventType) {
    List<Task> tasks = eventService.getEvent(eventType)
            .stream()
            .map(Task::new)
            .collect(Collectors.toList());
    taskRepository.saveAll(tasks);
    return tasks.size();
}

那么如何使用 Quarts 和事务正确创建集成测试?

测试class使用存储库的findAll方法,如果你尝试获取LAZY初始化方法,你会得到这个异常。

在断言中:

t.getEvent().getEventType() // can throw it
actual.get(0).getEvent() // can throw it

为了避免这种情况,您可以将其设为事务性或优先获取类型。

在 REPEATABLE READ 下,第二个 SELECT 保证至少显示从第一个 SELECT 返回的未更改的行。在那一分钟内,并发事务可能会添加新行,但无法删除或更改现有行。

Difference between "read commited" and "repeatable read"