4 Replies Latest reply on Nov 10, 2015 9:10 AM by tomjenkinson

    Resuming JTA transaction after Java 8 CompletableFuture in initial thread

    galder.zamarreno

      I'm trying to execute a JTA transaction across multiple async CompletableFutures that are composed with each other.

       

      I'm able to pass the transaction from one thread to the other by suspending the transaction and resuming it in the async Supplier passed to CompletableFuture.supplyAsync(). However, I'm having trouble resuming back the transaction in the thread that suspended it after the CompletableFuture completes.

       

      I've written some pseudo code here to better show the scenario and there are some possible solutions there but none work so far.

       

      I can't use whenComplete() because that would be run with T2 and in fact I need T1 to run it since I need to resume the transaction in T1, see "whenComplete.java" in pseudo code for this option.

       

      I have tried to hack whenCompleteAsync() to see if I can get it to execute the section with the original thread, but although the Executor.execute() callback is called, I can get the passed in Thread to run the Runnable.

       

      Any other ideas how to solve this?

        • 1. Re: Resuming JTA transaction after Java 8 CompletableFuture in initial thread
          mmusgrov

          I may be misunderstanding what you want but this looks more like a question on how to structure a java program - don't you simply need ensure that thread T1 rendezvous' with the asynchronous thread T2 before trying to resume the transaction in thread T1.

          • 2. Re: Resuming JTA transaction after Java 8 CompletableFuture in initial thread
            tomjenkinson

            Hi Galder, thanks for the question. Please can you expand on "However, I'm having trouble resuming back the transaction in the thread that suspended it after the CompletableFuture completes."?

            • 3. Re: Resuming JTA transaction after Java 8 CompletableFuture in initial thread
              tomjenkinson

              While trying to replicate the issue I came up with the following which works and is pretty much as you have it but I didn't know what R return = means so I had to guess sorry

               

                  private Transaction suspendedTx;

               

               

                  @Test

                  public void test() throws Exception

                  {

                      javax.transaction.TransactionManager transactionManager = com.arjuna.ats.jta.TransactionManager.transactionManager();

                      transactionManager.begin();

                      suspendedTx = transactionManager.suspend();

                      System.out.println("Suspended main");

                      CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {

                          try {

                              transactionManager.resume(suspendedTx);

                              System.out.println("Resumed");

                          } catch (Exception e) {

                              e.printStackTrace();

                          }

                          try {

                              Thread.sleep(2000);

                          } catch (Exception e) {

                              e.printStackTrace();

                          }

                          try {

                              suspendedTx = transactionManager.suspend();

                              System.out.println("Suspended");

                          } catch (Exception e) {

                              e.printStackTrace();

                          }

                          return 100;

                      });

                      completableFuture.get();

                      transactionManager.resume(suspendedTx);

                      System.out.println("Resumed main");

                      transactionManager.commit();

                  }

               

              It took a minute or two because I wasn't calling transactionManager.begin() - I wonder if you have made a similar mistake or whether I misunderstood your problem?

              • 4. Re: Resuming JTA transaction after Java 8 CompletableFuture in initial thread
                tomjenkinson

                Hi Galder,

                 

                I have marked my answer as correct - please do let me know if it didn't address your question.

                 

                Many thanks for your interest in Narayana,

                Tom