不同线程上的 Quarkus 事务

Quarkus Transactions on different thread

我有一个带有异步端点的 quarkus 应用程序,它创建一个具有默认属性的实体,在请求方法中启动一个新线程并执行一个长 运行 作业,然后 returns 实体作为供客户跟踪的响应。

@POST
@Transactional
public Response startJob(@NonNull JsonObject request) {
        // create my entity
        JobsRecord job = new JobsRecord();
        // set default properties
        job.setName(request.getString("name"));

        // make persistent
        jobsRepository.persist(job);
        
        // start the long running job on a different thread
        Executor.execute(() -> longRunning(job));

        return Response.accepted().entity(job).build();
    }

此外,长 运行 作业将在实体运行时对其进行更新,因此它也必须是事务性的。然而,数据库实体并没有得到更新。

这些是我面临的问题:

  1. 我收到以下警告:
ARJUNA012094: Commit of action id 0:ffffc0a80065:f2db:5ef4e1c7:0 invoked while multiple threads active within it.
ARJUNA012107: CheckedAction::check - atomic action 0:ffffc0a80065:f2db:5ef4e1c7:0 commiting with 2 threads active!

似乎是应该避免的事情。

  1. 我试过 @Transaction(value = TxType.REQUIRES_NEW) 没用。

  2. 我尝试在 longRunning 上使用 API Approach 而不是 @Transactional 方法,如下 guide 中所述:

@Inject UserTransaction transaction;
.
.
.
try {
    transaction.begin();
    jobsRecord.setStatus("Complete");
    jobsRecord.setCompletedOn(new Timestamp(System.currentTimeMillis()));
    transaction.commit();
} catch (Exception e) {
    e.printStackTrace();
    transaction.rollback();
}

但随后我收到错误:ARJUNA016051: thread is already associated with a transaction!ARJUNA016079: Transaction rollback status is:ActionStatus.COMMITTED

  1. 这次我在启用 context propagation 的情况下再次尝试了声明式和基于 API 的方法。但是还是不行。

  2. 最后,基于第三种方法,我认为将 @Transactional 保留在 Http 请求处理程序上,并在没有声明或基于 API 的情况下保留 longRunning交易方法会起作用。但是数据库仍然没有更新。

显然我误解了 JTA 和上下文传播的工作原理(以及其他)。

有没有一种方法(甚至是一种设计模式)允许我在 quarkus Web 应用程序中异步更新数据库实体?还有为什么我采取的任何方法都没有任何效果?

使用 quarkus 1.4.1.Final 与 ext: [agroal, cdi, flyway, hibernate-orm, hibernate-orm-panache, hibernate-validator, kubernetes-client, mutiny, narayana-jta, rest-客户端、resteasy、resteasy-jackson、resteasy-mutiny、smallrye-context-propagation、smallrye-health、smallrye-openapi、swagger-ui]

您应该 return 来自 JAX-RS 资源方法的异步类型,事务上下文将在异步阶段执行时可用。 quarkus guide on context propagation.

中有一些相关文档

我将从查看 getting started quickstart 等反应性示例之一开始。尝试使用 @Transactional 注释每个资源端点,异步代码将 运行 使用事务上下文。