Javax (Payara) @Asynchronous and transactional

21 views Asked by At

I need to execute an asynchronous task that requires multiple database updates to be committed during its work. This task is called by a JAX-RS API resource method and it is well asynchronous but no transaction is committed and no exception is thrown.

Everything is powered by a PayaraMicro 5.2022.5.

// Resource.java
public class Resource {
  @Inject private Dao dao;
  @Inject private Service service;

  @POST
  public Entity post() {
    var entity = new Entity();
    entity.setStatus("READY");

    // Requires to be committed before asynchronous task : OK
    this.dao.persistTransac(entity);

    // Requires to be asynchronous : OK
    this.service.doSomethingAsync(entity);

    return entity;
  }
}
// Dao.java
public class Dao {
  @Inject private EntityManager em;

  public void persist(Entity entity) {
    this.em.persist(entity);
  }

  @Transactional(Transactional.TxType.REQUIRES_NEW)
  // tried with this :
  // @TransactionAttribute(TransactionAttributeType.REQUIRED)
  public void persistTransac(Entity entity) {
    this.persist(entity);
  }

  public void update(Entity entity) {
    this.em.update(entity);
  }

  @Transactional(Transactional.TxType.REQUIRES_NEW)
  // tried with this :
  // @TransactionAttribute(TransactionAttributeType.REQUIRED)
  public void updateTransac(Entity entity) {
    this.update(entity);
  }
}
// Service.java
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class Service {
  @Asynchronous
  // tried with this :
  // @Transactional(Transactional.TxType.REQUIRED)
  // tried with this :
  // @TransactionAttribute(TransactionAttributeType.REQUIRED)
  // and tried with both of them
  public void doSomethingAsync(Entity entity) {
    this.doSomething();

    entity.setStatus("WORKING");

    // Requires to be committed : NOT OK
    this.dao.updateTransac(entity);

    this.doSomethingElse();

    entity.setStatus("FINISHED");

    // Requires to be committed : NOT OK
    this.dao.update(entity);
  }

  private void doSomething() { /* */ }
  private void doSomethingElse() { /* */ }
}

Is it possible ? If so, what am I doing wrong ?

Thank you by advance !

0

There are 0 answers