Search code examples
transactionsquarkusmutiny

Cannot start a JTA transaction from the IO thread


I'm trying to test some reactive code implemented with mutiny on quarkus 2.2. This code do some sql query and I want a transactional method.

From my knowledge , for testing reactive code I have to await explicitly the result. But when there is transaction I got a io.quarkus.runtime.BlockingOperationNotAllowedException: Cannot start a JTA transaction from the IO thread.

here the test :

  void myTest() throws InterruptedException, SystemException, NotSupportedException {
    final Prestation prestation = Prestation.builder().build();
    final Uni<Uni<Integer>> uniUni = Uni.createFrom().voidItem().onItem().transformToUni(unused -> prestationCreate.upsert(prestation)).onItem()
            .transformToUni(aBoolean -> {
                return prestationClosedThePreviousDaySelect.select2Multi(LocalDate.of(2021, 04, 29))
                        .collect().asList();
            })
            .onItem()
            .transformToUni(prestations -> Uni.createFrom().item(prestationRepository.deleteAll()))
            .runSubscriptionOn(Infrastructure.getDefaultExecutor());

    final UniAssertSubscriber<Uni<Integer>> uniUniAssertSubscriber = uniUni.subscribe().withSubscriber(UniAssertSubscriber.create());
    uniUniAssertSubscriber.awaitItem()
            .assertCompleted();
}

With this code the exception will be thrown at the last line.

If I replace the last line with listUniAssertSubscriber.assertCompleted();, tests fails with "Expected a completion event, but didn't received it."

Anybody know if there is a way to test reactive code with transaction ?


Solution

  • (copying my comment, confirmed by the reporter)

    prestationClosedThePreviousDaySelect.select2Multi produces its result on an I/O thread (you can add .log() to check), and deleteAll is transactional?. In that case, it's not a runSubscriptionOn that you need, but an emitOn(...) just before the onItem()