3 Replies Latest reply on Sep 28, 2016 5:27 PM by karlnicholas

    Cannot use BMT in @Scheduled service

    karlnicholas

      When injecting a `@Resource private UserTransaction tx;`, a `TransactionReaper` terminates kills my `UserTransaction` after 5 minutes no matter what. Since it's a batch update, I need more than 5 minutes.

       

      Here is a simple piece of code that doesn't work.

      @EJB private TestFiveMinuteBatch testFiveMinuteBatch;
      
      @Schedule(second="0", minute="8", hour="10", persistent=false)
      public void updateTest() {
          testFiveMinuteBatch.test();
      }
      
      @Stateless
      @TransactionManagement(TransactionManagementType.BEAN)
      public class TestFiveMinuteBatch {
          @Resource private UserTransaction tx;
          public void test() {
              for ( int i=0; i < 6; ++i ) {
                  System.out.println("Minute: " + i);
                  try {
                      Thread.sleep(60000);
                  } catch (InterruptedException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
              }
          }
      }
      

      After five minutes I get this warning:

      10:13:00,034 WARN  [com.arjuna.ats.arjuna] (Transaction Reaper) ARJUNA012117: TransactionReaper::check timeout for TX 0:ffffac1f6209:-595568e4:57e80419:e in state  RUN

      10:13:00,039 WARN  [com.arjuna.ats.arjuna] (Transaction Reaper Worker 0) ARJUNA012121: TransactionReaper::doCancellations worker Thread[Transaction Reaper Worker 0,5,main] successfully canceled TX 0:ffffac1f6209:-595568e4:57e80419:e

      10:13:00,130 INFO  [stdout] (EJB default - 1) Minute: 5

      Then when the service terminates I get this error:

      10:14:00,131 WARN  [com.arjuna.ats.arjuna] (EJB default - 1) ARJUNA012077: Abort called on already aborted atomic action 0:ffffac1f6209:-595568e4:57e80419:e

      10:14:00,163 ERROR [org.jboss.as.ejb3.timer] (EJB default - 1) WFLYEJB0020: Error invoking timeout for timer: [id=8a8f4546-28d0-491e-85a6-f668f58ab5dc timedObjectId=opca-ear.opca-ejb.ScheduledService auto-timer?:true persistent?:false timerService=org.jboss.as.ejb3.timerservice.TimerServiceImpl@31fe8c3e initialExpiration=null intervalDuration(in milli sec)=0 nextExpiration=Mon Sep 26 10:08:00 PDT 2016 timerState=IN_TIMEOUT info=null]: javax.ejb.EJBTransactionRolledbackException: Transaction rolled back

        at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleEndTransactionException(CMTTxInterceptor.java:137)

        at org.jboss.as.ejb3.tx.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:117)

        at org.jboss.as.ejb3.tx.TimerCMTTxInterceptor.endTransaction(TimerCMTTxInterceptor.java:67)

        at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:279)

        at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:327)

        at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:239)

        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

        at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41)

        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

        at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:100)

        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

        at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:437)

        at org.jboss.as.ejb3.concurrency.ContainerManagedConcurrencyInterceptor.processInvocation(ContainerManagedConcurrencyInterceptor.java:110)

        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

        at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64)

        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

        at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)

        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

        at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:54)

        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

        at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:64)

        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

        at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356)

        at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:636)

        at org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:61)

        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

        at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356)

        at org.jboss.invocation.PrivilegedWithCombinerInterceptor.processInvocation(PrivilegedWithCombinerInterceptor.java:80)

        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)

        at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)

        at org.jboss.as.ejb3.timerservice.TimedObjectInvokerImpl.callTimeout(TimedObjectInvokerImpl.java:99)

        at org.jboss.as.ejb3.timerservice.CalendarTimerTask.invokeBeanMethod(CalendarTimerTask.java:64)

        at org.jboss.as.ejb3.timerservice.CalendarTimerTask.callTimeout(CalendarTimerTask.java:53)

        at org.jboss.as.ejb3.timerservice.TimerTask.run(TimerTask.java:157)

        at org.jboss.as.ejb3.timerservice.TimerServiceImpl$Task$1.run(TimerServiceImpl.java:1215)

        at org.wildfly.extension.requestcontroller.RequestController$QueuedTask$1.run(RequestController.java:497)

        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

        at java.lang.Thread.run(Thread.java:745)

        at org.jboss.threads.JBossThread.run(JBossThread.java:320)

      Caused by: javax.transaction.RollbackException: WFLYEJB0447: Transaction 'TransactionImple < ac, BasicAction: 0:ffffac1f6209:-595568e4:57e80419:e status: ActionStatus.ABORTED >' was already rolled back

        at org.jboss.as.ejb3.tx.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:98)

        ... 38 more

      Any ideas what's going on?
        • 1. Re: Cannot use BMT in @Scheduled service
          tomjenkinson

          I imagine an EJB timer is a CMT so that will cause the updateTest call to create a CMT that times out (default timeout is 300 with WFLY)

          • 2. Re: Cannot use BMT in @Scheduled service
            karlnicholas

            Yes, ok. I was having trouble for some reason I don't remember at the moment, but I put it back to CMT logic and use this annotation on the @Schedule service:

             

             

            If you want a transaction add @org.jboss.ejb3.annotation.TransactionTimeout(value=1, unit=HOURS) to the @Schedule method.

             

            UserTransaction.setTransactionTimeout actually sets the timeout for newly created transactions by that thread, it will not affect an existing CMT tranaction.

            • 3. Re: Cannot use BMT in @Scheduled service
              karlnicholas

              I also got this, which was the basic problem I was having since the @Singleton bean that was holding the @schedule method was not BMT. I have to make sure that everything in the calling sequence is BMT, which I knew, but didn't think through the fact that the highest level bean was also starting a CMT transaction (if that makes sense).

               

              The Schedule method is on a different bean, so it will start a transaction. The transaction will then time out and an exception will be thrown when it is commited. You need both beans to use BMT.