10 Replies Latest reply on Feb 4, 2009 1:25 PM by fatboysuns

    Problems with Transaction Manager

      Hi,
      My app uses Spring and Jta for database transactions and I am trying some transaction configuration for my cache to work along with that ,
      I am facing a couple of problems when doing that.
      1. I saw specific mentions of JBossTransactionManagerLookup being the default transaction manager of Jboss cache. When using it as TransactionManagerLookupClass, I get a
      java.lang.ClassCastException: org.jboss.tm.TxManager.
      When trying to import I saw JBossTransactionManagerLookup available in 2 packages ie, org.jboss.cache.transaction.JBossTransactionManagerLookup and import org.hibernate.transaction.JBossTransactionManagerLookup. I get a class cast when using both.

      2. When specifying the transactionManagerClass as the GenericTransactionManager, The application complains of having transaction Manager already registered to the Dummy transaction Manager. The exception is binding of DummyTransactionManager failed
      javax.naming.NameAlreadyBoundException.

      I am not specifying the dummy transaction manager anywhere. When I did step thru the cache code, i couldnt find any place where jboss cache was setting this. However when I specify no transactionManagers the actual value set in the transactionManager of cache class was null. I am very confused. I cant set it after creation of the cache too as this is not a dynamic property. I am not sure What I have to do. My configuration setting is very simple

      String tmlc = JBossTransactionManagerLookup.class.getName();
      configuration.setTransactionManagerLookupClass(tmlc);
      configuration.setIsolationLevel(IsolationLevel.READ_COMMITTED);
      configuration.setCacheMode(CacheMode.REPL_SYNC);
      configuration.setLockParentForChildInsertRemove(true);
      configuration.setLockAcquisitionTimeout(15000);

      I Saw some other posts mentioning the same problem. I am not sure what is wrong ? Any help to resolve this is much appreciated.

      Regards
      Sundar

        • 1. Re: Problems with Transaction Manager

          This is the stacktrace, if it helps.

          javax.naming.NameAlreadyBoundException
          at org.jnp.server.NamingServer.bind(NamingServer.java:144)
          at org.jnp.interfaces.NamingContext.bind(NamingContext.java:566)
          at org.jnp.interfaces.NamingContext.bind(NamingContext.java:531)
          at javax.naming.InitialContext.bind(InitialContext.java:359)
          at org.jboss.cache.transaction.DummyTransactionManager.getInstance(DummyTransactionManager.java:61)
          at org.jboss.cache.transaction.GenericTransactionManagerLookup.getTransactionManager(GenericTransactionManagerLookup.java:113)
          at org.jboss.cache.factories.TransactionManagerFactory.construct(TransactionManagerFactory.java:68)
          at org.jboss.cache.factories.ComponentRegistry.getOrCreateComponent(ComponentRegistry.java:312)
          at org.jboss.cache.factories.ComponentRegistry.invokeInjectionMethod(ComponentRegistry.java:273)
          at org.jboss.cache.factories.ComponentRegistry$Component.injectDependencies(ComponentRegistry.java:939)
          at org.jboss.cache.factories.ComponentRegistry.registerComponent(ComponentRegistry.java:249)
          at org.jboss.cache.factories.ComponentRegistry.getOrCreateComponent(ComponentRegistry.java:319)
          at org.jboss.cache.factories.ComponentRegistry.invokeInjectionMethod(ComponentRegistry.java:273)
          at org.jboss.cache.factories.ComponentRegistry$Component.injectDependencies(ComponentRegistry.java:939)
          at org.jboss.cache.factories.ComponentRegistry.registerComponent(ComponentRegistry.java:249)
          at org.jboss.cache.factories.InterceptorChainFactory.createInterceptor(InterceptorChainFactory.java:60)
          at org.jboss.cache.factories.InterceptorChainFactory.buildInterceptorChain(InterceptorChainFactory.java:75)
          at org.jboss.cache.factories.InterceptorChainFactory.construct(InterceptorChainFactory.java:225)
          at org.jboss.cache.factories.ComponentRegistry.getOrCreateComponent(ComponentRegistry.java:312)
          at org.jboss.cache.factories.ComponentRegistry.invokeInjectionMethod(ComponentRegistry.java:273)
          at org.jboss.cache.factories.ComponentRegistry$Component.injectDependencies(ComponentRegistry.java:939)
          at org.jboss.cache.factories.ComponentRegistry.registerComponent(ComponentRegistry.java:249)
          at org.jboss.cache.DefaultCacheFactory.bootstrap(DefaultCacheFactory.java:155)
          at org.jboss.cache.DefaultCacheFactory.createAndWire(DefaultCacheFactory.java:141)
          at org.jboss.cache.DefaultCacheFactory.createCache(DefaultCacheFactory.java:120)
          at org.jboss.cache.DefaultCacheFactory.createCache(DefaultCacheFactory.java:105)

          • 2. Re: Problems with Transaction Manager
            manik

            What JTA environment are you running in? You shouldn't be relying on the DummyTransactionManager.

            • 3. Re: Problems with Transaction Manager

              I am using Springs transaction management on Jboss 4.05. I did read in the troubleshoot column of the cache website that this might be due to the cache getting loaded first and Jboss getting initialized a little later. Is there a hack for this?

              http://jboss.org/community/docs/DOC-10288;jsessionid=4B56938880A7A5ECED34EC2CEAD2AC71

              My requirement is to start a thread that loads all the data I need into the cache.

              • 4. Re: Problems with Transaction Manager

                One more thing, I tried to start a thread which would act as the loader. I tried this stupid approach of making it sleep for some time and then call the method to load the cache. The idea being that the cache would get evoked only after the server started up and the jboss transaction manager would be in place.
                Even after doing this, the cache was getting bound to dummytransactionManager only. My code was


                private boolean retryAndLoadCache(Thread t) {
                for (int i = 0; i < 3; i++) {
                try {
                t.sleep(20000);
                boolean cacheLoaded = checkIfCacheLoaded(); //sets up the configuration for my singleton cache object
                if (cacheLoaded) {
                return true;
                } else {
                cacheFactory.destroyCache(); // calls cache.destroy and makes the cache object back to null.
                log.info("destroying cache");
                }
                } catch (NameAlreadyBoundException nabe) {
                //log.error(nabe, nabe);
                log.info("Retrying " + i + "th time.");
                } catch (InterruptedException e) {
                log.error(e, e);
                }
                }
                return false;
                }

                • 5. Re: Problems with Transaction Manager

                  Another update when I was debugging the jboss cache code. In GenericTransactionManager class, ctx.lookup(knownJNDIManager[0]) seems to be returning org.jboss.tm.TxManager, but jboss cache seems to expecting javax.transaction.TransactionManager.

                  Is there a solution for this?

                  • 6. Re: Problems with Transaction Manager
                    manik

                    Have you tried using the JBossTransactionManagerLookup instead of the GenericTransactionManagerLookup?

                    • 7. Re: Problems with Transaction Manager

                      Yes I have, When I try JbossTransactionManagerLookup, I get a classcast exception. I did try the JbossstandaloneJTAlookup too with no luck.

                      I have tried to even upgrade my jboss from 4.05 to 4.23 with no luck. The surprising thing there was, When I ran a test to basically typecast arjuna.ats.JbossATX.transactionManager, which was the transactionManager that was getting returned in 4.23, to javax.transaction.TransactionManager, It ran fine. I did see that it had a parent class which implements TransactionManager. But When I ran I via the app, I got a classcast Exception again. I am not sure what I should do.

                      This was just a test as I dont think I can upgrade Jboss in production anytime soon too. Do you think I should use jboss-cache 2.x version instead of the 3.x version? If so which version does support jboss searchable?

                      Any help would be great.
                      Thanks

                      • 8. Re: Problems with Transaction Manager
                        manik

                        You need JBC core 3 for JBCS.

                        If you intend to deploy JBCS and JBC core 3 on AS 4.x, I suggest you first have a look at https://www.jboss.org/community/docs/DOC-10254


                        • 9. Re: Problems with Transaction Manager
                          brian.stansberry

                          Just a thought: the TransactionManagerLookup interface is meant to be a plug-in point. You've been looking at the impls, so you can see that they aren't doing anything particularly complex. So if need be you can write your own impl that works in your environment.

                          • 10. Re: Problems with Transaction Manager

                            The solution :
                            This is how I got my TransactionManager from JBoss server

                            TransactionManager tm = (org.jboss.tm.TxManager) new InitialContext().lookup("java:/TransactionManager");

                            and I used this to inject into runtime config.

                            Jboss cache was doing one of the 2 things

                            1. In GenericTransactionManagerLookup the code is

                            if (jndiObject instanceof TransactionManager)
                             {
                             tm = (TransactionManager) jndiObject;
                             log.debug("Found TransactionManager for " + knownJNDIManager[1]);
                             return;
                             }
                            

                            The "instanceof" condition was failing as class org.jboss.tm.TXManager implements TransactionManager

                            2. Within JBossTransactionManagerLookup this statement was throwing a class cast Exception
                            return (TransactionManager) new InitialContext().lookup("java:/TransactionManager");


                            Again for the same reason.

                            When I do upgrade to Jboss 4.2.3 Jboss was returning me a different and the same problems existed.

                            When I downgrade the jboss-cache version, The exact same code was present , which meant I was getting the exact same problems.

                            I am not sure on how to approach this problem as the code I have done is dirty as it uses "Jboss server" specific jars in classpath to compile.

                            Please do suggest on how to handle this.

                            I have another question though. Spring manages my transactions for all my service classes. And all my jboss cache calls are happening from within a service class. If spring calls its "rollback / commit" at End of teh service method, would it be rolled back / committed to the jboss cache too?

                            Thanks for your help so far. I totally appreciate you taking the time to answer me.

                            -Sundar