1 2 Previous Next 25 Replies Latest reply on Mar 28, 2008 5:02 PM by jcstaff Go to original post
      • 15. Re: Create timer -
        oskar.carlstedt

        Hmm... and now you're back where you started, aren't you?

        This is a pretty annoying problem. Is there a working example of doing this within an EJB? Is the following solution possible?

        @Stateless
        @Local
        public class A {
        
         @EJB
         B b;
        
         /**
         * this method is the one that is invoked by the 'user'
         **/
         public void someBusinessMethodThatHasToCreateATimer(...) {
         ...
         b.startTimer();
         }
        
        
         /**
         * this method will do the timeout job
         **/
         public void handleTimeout(Timer timer) {
         ...
         }
        
        }
        
        
        /**
        * this is a wrapper class to get a new transaction that only has to
        * deal with one data source in its own transaction.
        **/
        @Stateless
        @Local
        public class B {
        
         @Resource
         EJBContext ejbContext;
        
         @EJB
         A a;
        
         /**
         * this method is invoked by A. the result shall be
         * a created and persisted timer.
         **/
         public void startTimer() {
         ejbContext.getTimerService().createTimer(...);
         }
        
         /**
         * handles the timeout and will not do anything more
         * than just call the handleTimeout in A.
         **/
         @Timeout
         public void timeout(Timer timer) {
         a.handleTimeout(timer);
         }
        
        }
        
        


        This is not a nice solution using a circular reference, but is there any other way get around this problem without reconfiguring JBoss?


        Cheers
        /Oskar


        • 16. Re: Create timer -
          rruppel

          First of all, thanks very much for starting helping me...

          let me say what I am trying to do:

          get an interval from database and use this interval to schedule my timer

          but, I make this twice in the code

          1. when the appplication is deployed

          2. at the end of each execution I schedule it again (this is the problem!)

          ok, now I will write what I did:

          first I have made a mistake at my first code and when I corrected it, the error has changed to:


          Trying to start a new tx when old is not completed


          well... this error is exactly what I am doing.... (I agree with the error...lol) so how can I commit the transaction and then call the other method to shedule?

          I tryed some things, and what make me confuse is:

          when the application is deployed it schedules fine the timer.... maybe because it calls the "schedule" method through a Local interface, like you suggested

          I suppose that calling the method through the Local interface completes the transactions before calling the method.... but is it right? (I think it shouldnt)

          well... like the @Timeout method is the one that has to schedule the next execution... i cant call the schedule method through a @Local interface (only if it would be possible to have an instance of the own class injected on it... I can try this... but its ugly)

          I will help any advice... thanks


          ps: I havent seem oscar message before

          oscar, I thought using this solution, but I know that circular reference is a problem with jboss (at least ive never found a solution)

          thanks for trying to help







          • 17. Re: Create timer -
            rruppel

            ops... i opened a second quote instead of closing it

            someone can edit please

            thanks

            • 18. Re: Create timer -
              alrubinger

               

              "rruppel" wrote:
              oscar, I thought using this solution, but I know that circular reference is a problem with jboss (at least ive never found a solution)


              Use @IgnoreDependency on one of the @EJB instances to avoid the dependency cycle.

              S,
              ALR

              • 19. Re: Create timer -
                oskar.carlstedt

                I'm using JBoss 4.2.2.GA. Do I still have to use the JBoss specific annotation @IgnoreDependency or is it possible to do this in a pure standard java ee way?

                Kind regards
                /Oskar

                • 20. Re: Create timer -
                  alrubinger

                   

                  "oskar.carlstedt" wrote:
                  Do I still have to use the JBoss specific annotation @IgnoreDependency or is it possible to do this in a pure standard java ee way?


                  Because handling of cyclic dependencies is not defined by EJB3 Core Specification, it's up to implementation to provide its own mechanism. So short answer, you gotta use our annotations or XML equivalent in jboss.xml. :)

                  S,
                  ALR

                  • 21. Re: Create timer -
                    oskar.carlstedt

                    Ooopss... Then we are in trouble...

                    Is it possible to configure MySQL and Hypersonic with a XA data sources. What we want to do is to use the default data source as the timer data source and then use JPA with an underlying MySQL (with MyISAM tables) and get this to work. A config example would be great.

                    Thanks a lot for your help!
                    Kind Regards

                    /Oskar

                    • 22. Re: Create timer -
                      alrubinger

                      Did you check:

                      http://wiki.jboss.org/wiki/Wiki.jsp?page=ConfigDataSources

                      ?

                      Also, take a look at docs/examples/jca in your distribution.

                      I don't know if Hypersonic supports XA or has an XA-aware Driver. I've used XA with MySQL 5.x before, but MyISAM doesn't support commit/rollback, so that defeats the purpose of transactional integrity; you'd have to opt for InnoDB or the new Falcon persistence engine.

                      Any reason you need to keep Hypersonic around? For Production use you should be stripping this out anyway...

                      S,
                      ALR

                      • 23. Re: Create timer -
                        rruppel

                        in my case, i want keep the Timer at the Hypersonic because:

                        1. The production database is very busy, and sometimes the database is off (I mean, its avaliable "only" 98% of the time, but I cant trust on 98%, and the hypersonic is 99,99% avaliable, because it is used only for the timers, in fact, untill now the hypersonic is 100% avaliable)

                        2. I wont need change the default jboss configurations (the DatabaseTimer at ejb-deployer.xml)

                        and I have discovered another thing:

                        the suggestion about calling the "shedule" method trough the @Local interface does not work!

                        I thought it had worked, but now I can see the difference:

                        when the method "contextInitialized" of my servlet class is called, this method isnt in a EJB Transaction... thats why it can call the "schedule" method without problems....

                        so, now, inside a method managed by the container I want to use two datasources, this is the main problem

                        first, one datasource to get the interval

                        then, persist the timer

                        is there a simple way to complete the first transaction before call the "schedule" method?

                        I thought using interceptors to schedule the method after the execution of the first method, but then I read the docs and it says that the interceptors use the same transaction

                        I am thinking about just changing the jta aspect to allow multiple datasources.... because I can trust my data wont be corrupted (because they are two different transactions in fact)

                        thanks again for your help

                        regards,

                        RRR

                        • 24. Re: Create timer -
                          rruppel


                          This way here it worked:


                          
                          class Parameters{
                          void getInterval();
                          
                          }
                          
                          
                          class Scheduler{
                          
                          @IgnoreDependency
                          @EJB
                          Executor executor;
                          
                          
                          void schedule(){
                           executor.schedule();
                          }
                          
                          
                          }
                          
                          
                          class Executor{
                          
                          @EJB Parameter parameters;
                          
                          @EJB Scheduler scheduler;
                          
                          @TransactionAttribute(REQUIRES_NEW)
                          void schedule(){
                          schedule(parameter.getInterval());
                          
                          }
                          
                          void schedule(long interval){
                          timerService.createTimer(interval, "myTimer");
                          }
                          
                          
                          @Timeout
                          execute(Timer timer){
                          
                          // do lots of things
                          
                          scheduler.schedule();
                          
                          }
                          
                          
                          }
                          
                          
                          class Servlet{
                          
                          // not managed by container
                          void contextInitialized(){
                          
                          Executor executor = lookup(...);
                          executor.schedule();
                          
                          }
                          
                          
                          }
                          
                          



                          what I cant understand is:

                          why it doesnt work if I call the "schedule" method of Executor inside the "execute" method ?

                          reading again the responses I thought that the answer could be:


                          You are calling the schedule() method using a raw Java method call


                          because the "execute" method call the "schedule" method like a raw java method, so it wont see the "REQUIRES_NEW" attribute...

                          but the example I posted above works, and the "REQUIRES_NEW" attribute has to be above the "schedule" method (I testes changing it to the other schedule method or putting it on both, but only this way at the example works)

                          and inside the schedule method, I use the datasource1 at "getInterval" and then I call the method schedule

                          so... its strange this behavior for me....

                          someone who knows why can explain it please?

                          another interesting thing is: I was upset with the fact that I would have to use a non-default jar (jboss-annotations-ejb3.jar) which includes the IgnoreDependency annotation, but I tested it without this jar and it worked (strange)...

                          thanks again for your help... the problem is solved... I just wanna understand now

                          regards,

                          RRR

                          • 25. Re: Create timer -
                            jcstaff

                            You say your schedule works, but nowhere are you specifically stating you are interacting with an @Entity that would cause the XA transaction issue. The post a few back specifically showed the actions occurring in the same transaction. The following would not work without XA support.


                            public void firstMethod(){

                            entyManager.persist(something);
                            schedule();
                            }


                            If you only interact with EJBTimers and other session beans, then there is no problem since you only have a single resource (the one supporting EJBTimers) involved in the transaction.

                            1 2 Previous Next