10 Replies Latest reply on Apr 25, 2006 9:39 AM by dimitris

    TimerService timeout fired within timer-creation transaction

    tzwoenn

      Imagine the following scenario:

      A session bean creates a timer with application depending timeout duration. Due to some some network IO the same transaction runs a bit longer... longer than the timeout duration of the timer.

      In the specification nothing is mentioned about such cases, but from my understanding of transactional behaviour a timer can not be fired as long as the transaction in which the timer was created has been committed. But Jboss does so as far as I see.

      What if the same transaction is rolled back after timer creation? The creation should have been canceled too, so the timer won't be fired any more. So the only way to deal with this problem is to delay timer expiration as long as the creating transaction committed.

      I would appreciate to know, if this problem is dicussed before. So please tell me, if I am wrong :)

        • 1. Re: TimerService timeout fired within timer-creation transac
          starksm64

          Should be fixed as part of:
          http://jira.jboss.com/jira/browse/JBAS-1926

          In terms of transactions, two timers run in two different transaction contexts so there is no relationship between the two. These are stateless components after all.

          • 2. Re: TimerService timeout fired within timer-creation transac
            tzwoenn

            By reading the issue details I think you misunderstood me:

            I was talking about a transaction, in which a timer was CREATED, but which was not committed yet. So the transaction might still be rolled back later, meaning for the timer also to be cancelled.

            But... what if this timer expires in between? You can not fire a timeout for this timer, but have to wait until the initial transaction rolls back or commits. Until then you can definitely decide, whether to fire the timer.

            • 3. Re: TimerService timeout fired within timer-creation transac
              dimitris

              AFAIR the timer will not be active until the transaction commits. If this is not so, (a) what jboss version are you using and (b) can you create a minimal testcase to show this?

              • 4. Re: TimerService timeout fired within timer-creation transac
                tzwoenn

                Running JBoss 4.0.3 SP1


                TimerTest.java

                package jadex.adapter.j2ee.examples.test;
                
                import javax.ejb.Remote;
                
                @Remote
                public interface TimerTest {
                
                 public void run();
                }
                


                TimerTestBean.java
                package jadex.adapter.j2ee.examples.test;
                
                import java.util.Properties;
                
                import javax.annotation.Resource;
                import javax.ejb.Stateless;
                import javax.ejb.TimedObject;
                import javax.ejb.Timeout;
                import javax.ejb.Timer;
                import javax.ejb.TimerService;
                import javax.ejb.TransactionAttribute;
                import javax.ejb.TransactionAttributeType;
                import javax.naming.InitialContext;
                import javax.naming.NamingException;
                
                @Stateless
                public class TimerTestBean implements TimerTest, TimedObject {
                
                 private static int counter = 0;
                
                 @Resource
                 private TimerService _timerService;
                
                 @TransactionAttribute(TransactionAttributeType.REQUIRED)
                 public void run() {
                 _timerService.createTimer(1000, counter++);
                 }
                
                 @Timeout
                 @TransactionAttribute(TransactionAttributeType.REQUIRED)
                 public void ejbTimeout(Timer timer) {
                 int count = (Integer) timer.getInfo();
                 System.out.println(count + ": Timer activated.");
                
                 _timerService.createTimer(1000, counter++);
                 System.out.println(count + ": new Timer created.");
                
                 try {
                 Thread.currentThread().sleep(5000);
                 } catch (InterruptedException e) {
                 }
                
                 System.out.println(count + ": Timer ends.");
                 }
                
                 public static void main(String[] args) throws NamingException {
                 Properties props = new Properties();
                 props.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
                 props.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
                
                 InitialContext ctx = new InitialContext(props);
                 TimerTest test = (TimerTest) ctx.lookup(TimerTest.class.getName());
                 test.run();
                 }
                }
                


                From my point of view every ejbTimeout() have to finish before another one can be fired. But JBoss fires the Timer, even the creation transaction has not committed yet.

                • 5. Re: TimerService timeout fired within timer-creation transac
                  dimitris

                  I'm looking at the code so it seem the timer will expire even before the create transaction is committed.

                  The standard is not very clear on that: ejb-2.1 spec, section 22.4.2 reads

                  "The container must call the ejbTimeout method after the timed duration or the absolute time specification in the timer creation method has passed. The timer service must begin to count down the timer duration upon timer creation..."

                  So it boils down to what is the timer creation time.

                  - TimerService.createTimer()
                  or
                  - tx commit after TimerService.createTimer() ?

                  • 6. Re: TimerService timeout fired within timer-creation transac
                    dimitris

                    Unless there are objections, I'll change this so that scheduling of the timer is delayed until commit time, when a transaction is active.

                    This will solve the problem of receiving a timeout, while still in the create transaction.

                    With this change, a secondary issue becomes what happens when scheduling a timeout, e.g. 500msecs from now, when commit takes place 1000ms from now.

                    The current behaviour is that by commit time the timeout will happen immediately after the commit. We could revise this so the timeout is recalculated to commit time + timeout.

                    There is no issue with absolute timeouts.

                    • 7. Re: TimerService timeout fired within timer-creation transac
                      tzwoenn

                      From EJB 3.0 Core Contracts, section 17.4.2:

                      Timers are persistent objects.


                      and from EJB 3.0 Core Contracts, section 17.4.3:
                      If the timer would have expired by the time that the transaction failed, the failure of the transaction should result in the expired timer providing an expiration notification after the transaction rolls back.


                      As far as I understand, Timers are transactional Resources. And if rollbacked Timer Cancellation results in Timer notifications, cancelled Timer Creations should result in non-firing Timers.

                      • 8. Re: TimerService timeout fired within timer-creation transac
                        dimitris

                        So we should be fine, as you won't receive any timeout during the timer creation transaction, even if the tx takes longer than the timeout.

                        • 9. Re: TimerService timeout fired within timer-creation transac
                          pietu

                           

                          "dimitris@jboss.org" wrote:
                          So we should be fine, as you won't receive any timeout during the timer creation transaction, even if the tx takes longer than the timeout.


                          Greets, we are currently using 4.0.4.CR2 and experiencing problem where first tx creates timer and data. Timer immediately timeouts (as it should be) but timeout method in second tx does not see db data created on first transaction (hence causing serious problems, database is SQL Server 2005 on TRANSACTION_READ_COMMITTED state). By testing, we see that about 1/3 of timeouts fail as above and 2/3 behave correctly.

                          Question: is this expected behavior on 4.0.4.CR2?

                          Thanks,

                          • 10. Re: TimerService timeout fired within timer-creation transac
                            dimitris

                            This is fixed in the release to come (4.0.4.GA)

                            http://jira.jboss.com/jira/browse/JBAS-2759