8 Replies Latest reply on Jul 13, 2008 6:42 PM by Phil Haigh

    Asychronous with EJB timer service

    Phil Haigh Novice

      Hi,


      I'm trying to create a process that kicks off a method to run 48 hours later (a reminder service).



      public String holdBooking()
      {
           log.info("Holding booking for #0", customer.getName());
           booking.setHeld(true);
      
           entityManager.persist(booking);
           entityManager.flush();
      
           // Schedule asychronous tasks          
           log.debug("Scheduling 48 hour email reminder");
           heldBookingTasks.fortyEightHourReminder(cal.getTime());
      
      
           return "/confirm.xhtml";
      }




      public void fortyEightHourReminder(@Expiration  Date dueDat)
      {
           log.info("Processing 48 hour reminder for held booking #0");
      }


         


      @Local
      public interface HeldBookingTasksI
      {
      
           @Destroy
           @Remove
           public abstract void destroy();
      
           @Asynchronous
           public abstract void fortyEightHourReminder(@Expiration  Date dueDate);
      
      }



      The net result of which is:



      2008-07-07 16:15:45,464 [ERROR jboss.logging.util.LoggerStream] org.jboss.resource.connectionmanager.JBossLocalXAException: Trying to start a new tx when old is not complete! old: < 131075, 27, 25, 1-a021167:c0dd:4871ea1d:beda021167:c0dd:4871ea1d:bf8




      I tried this using @Duration initially, and that just failed with a message:
      Could not enlist in transaction on entering meta-aware object
      and telling me to see previous warnings (of which there weren't any).


      Clearly I'm missing something - can anyone enlighten me?


      cheers


      phil

        • 1. Re: Asychronous with EJB timer service
          Phil Haigh Novice

          Sorry, should have said: this is Seam 2.0.1.GA on JBoss AS 4.2.2.

          • 2. Re: Asychronous with EJB timer service
            Daniel Roth Apprentice

            I do the same kind of stuff everywhere (and it works) and what I can see differ is that I often use either @Transactional or @TransactionAttribute (depending on if it is a ejb3 bean or not) with @Asynchronous. (see seam manual)
            I guess that when the the async method is called it is from a forked thread somewhere, where a transaction might not be present if one isn't using the annotations above. You could also try to start and commit a transaction manually to see if it makes a difference.


            However,the code you present shows no data source interaction, so it might be something completely else... :-)

            • 3. Re: Asychronous with EJB timer service
              Phil Haigh Novice

              Hi Daniel,


              Thanks for the reply! I think that the problem I'm having is that I'm using non-XA datasources, and a different DB for the JBoss AS default datasource than for my application.


              I know that I can make the datasources XA, which should resolve this, but I was wondering - can anyone tell me if it is possible to get JBoss AS to use a different datasource for each application? I.e. can I store timers etc in the application datasource somehow?


              • 4. Re: Asychronous with EJB timer service
                Daniel Roth Apprentice

                I don't really undertand what you mean by store, but if you mean store as in if I restart the server the timers will be present as they were before the restart, the answer is yes. Use quartz as timer dispatcher.

                • 5. Re: Asychronous with EJB timer service
                  System Administrator Expert

                  I have used EJB3 timers and Quartz timers successfully in a Seam app.


                  EJB3 timers are non-clusterable whereas Quartz timers are clusterable.


                  Regarding Quartz, read up on the job stores:


                  http://www.opensymphony.com/quartz/wikidocs/TutorialLesson9.html


                  By default, Quartz uses RAMJobStore and you will need to configure JDBCJobStore for your app.


                  It also looks like you need to setup XA for 2PC when you are trying to access more than one resource manager via the transaction manager or simply change the transaction type attribute settings for the methods in question in your session bean(s) that are causing the exception.


                  Setting up XA is easier with Oracle than SQL server...

                  • 6. Re: Asychronous with EJB timer service
                    Phil Haigh Novice

                    Thanks Arbi,


                    Yes, I currently have a datasource called JBossDB for the default JBoss AS datasource - this is where timers are persisted. I have another datasource myapp for my application.


                    I know if I go with XA, then this will work fine, but I am interested if there is an alternative. I.e. can I:



                    • Configure JBossAS to use a different EJB timer datasource for each application? (I presume not)

                    • Continue with 2 datasources, without going to XA? You suggest:



                    or simply change the transaction type attribute settings for the methods in question in your session bean(s) that are causing the exception.



                    How can I do this?


                    • 7. Re: Asychronous with EJB timer service
                      System Administrator Expert
                      I'm pretty sure that by default, EJB3 timer uses HSQLDB in the DefaultDS that is already in the default/deploy folder.  It is NOT recommended to use HSQLDB in a prod envmt according to a JBoss trainer we had recently.

                      <mbean code="org.jboss.ejb.txtimer.DatabasePersistencePolicy" name="jboss.ejb:service=EJBTimerService,persistencePolicy=database">
                          <!-- DataSourceBinding ObjectName -->
                          <depends optional-attribute-name="DataSource">jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
                          <!-- The plugin that handles database persistence -->
                          <attribute name="DatabasePersistencePlugin">org.jboss.ejb.txtimer.GeneralPurposeDatabasePersistencePlugin</attribute>
                          <!-- The timers table name -->
                          <attribute name="TimersTable">TIMERS</attribute>
                        </mbean>

                      above xml from C:\jboss-4.2.1.GA\server\default\deploy\ejb-deployer.xml

                      also see: http://www.redhat.com/docs/manuals/jboss/jboss-eap-4.2/doc/Server_Configuration_Guide/EJBs_on_JBoss-EJB_Timer_Configuration.html

                      you can also access this configuration data in JMX MBean View in http://localhost:8080/jmx-console.

                      I'm not sure if you can configure it to point to more than one datasource.

                      Secondly:

                      for example:

                      @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
                      public void foobar() {
                      ...
                      }

                      see JSR220-core for more on this...

                      hope that helps
                      • 8. Re: Asychronous with EJB timer service
                        Phil Haigh Novice
                        Yep, I'd already replaced HSQLDB with something more suitable. I'll give the second strategry a go with the NOT_SUPPORTED annotation, thanks.