5

In my current web application, i use @RestController with CompletableFuture result for all services.

Database operations are asynchronous (CompletableFuture methods), but i would like commit operations only before send result

i would like to commit database modifications after --save-- asynchronous ended (--save-- is a list of future business)

@RestController
public class MyController {
...

  @RequestMappping(...)
  public CompletableFuture<ResponseEntity<AnyResource>> service(...){

   CompletableFuture ...
   .thenCompose(--check--)
   .thenAsync(--save--)
   ...ect
   .thenApply(
      return ResponseEntity.ok().body(theResource);
    );
  }

}

-> i've tried with @Transactional, but it doesn't work (commit at the method's end but async method partially or not executed

-> Other way with programmatic :

@RequestMappping(...)
public CompletableFuture<ResponseEntity<AnyResource>> service(...){

DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can only be done programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

TransactionStatus status = this.platformTransactionManager.getTransaction(def);

CompletableFuture ...
   .thenCompose(--check--)
   .thenAsync(--save--)
   ...ect
   .thenApply(

this.platformTransactionManager.commit(status)

      return ResponseEntity.ok().body(theResource);
    );

}

An error occured "Cannot deactivate transaction synchronization - not active", supposed because not the same thread.

Is there a proper way, to use transactional with CompletableFuture ?

Jens Schauder
  • 65,795
  • 24
  • 148
  • 294
Fabien
  • 75
  • 1
  • 5

0 Answers0