5 Replies Latest reply on Apr 24, 2002 8:19 AM by sergioszy

    Informix Distributed Transaction Problem with JBoss

    jbossravi

      Hi!

      What I am trying to do is very simple. I have a client which is a Java application calling a Stateless Session Bean A. A does some updates to Informix table and then calls Stateless session bean B. B does some more updates. When the call returns to A, A throws a Runtime Exception. Now both beans have Transaction setting as required. The transaction should have got rolled back. But that is not what is happening. I guess it has something to do with the resource adaptor. I have configured the Connection Pool. But how do I configure the Resource adaptor.
      My jboss.jcml file is as follows


      ********************************************
      <?xml version="1.0" encoding="UTF-8"?>
      <!-- This is where you can add and configure your MBeans
      ATTENTION: The order of the listing here is the same order as
      the MBeans are loaded. Therefore if a MBean depends on another
      MBean to be loaded and started it has to be listed after all
      the MBeans it depends on.
      -->


      <!-- ==================================================================== -->
      <!-- Classloading -->
      <!-- ==================================================================== -->

      8083


      <!-- ==================================================================== -->
      <!-- JNDI -->
      <!-- ==================================================================== -->

      1099




      <!-- ==================================================================== -->
      <!-- Transactions -->
      <!-- ==================================================================== -->

      300

      <!-- Use this attribute if you need to use a specific Xid
      implementation
      oracle.jdbc.xa.OracleXid
      -->


      <!-- Uncomment to use Tyrex (tyrex.exolab.org) transaction manager plugin
      instead of the org.jboss.tm.TransactionManagerService and comment out
      the TransactionManagerService above

      ../conf/default/domain.xml

      -->





      <!-- ==================================================================== -->
      <!-- Security -->
      <!-- ==================================================================== -->

      <!-- Uncomment to enable the sample SRPVerifierStore service

      SRPDefaultVerifierSource
      SRPVerifierStore.ser

      -->
      <!-- Uncomment to enable the SRP login service

      SRPServerInterface
      SRPDefaultVerifierSource
      SRPAuthenticationCache
      10099

      -->

      <!-- JAAS security manager and realm mapping -->

      org.jboss.security.plugins.JaasSecurityManager


      <!-- Uncomment to enable the XML implementation of the JAAS policy

      DefaultSecurityPolicy
      sample_policy.xml

      -->

      <!-- ==================================================================== -->
      <!-- JDBC -->
      <!-- ==================================================================== -->


      org.hsql.jdbcDriver,org.enhydra.instantdb.jdbc.idbDriver,com.informix.jdbc.IfxDriver



      1476
      true
      default
      false



      InstantDB
      org.jboss.pool.jdbc.xa.wrapper.XADataSourceImpl

      jdbc:idb:../conf/default/instantdb.properties
      1200000

      10

      false
      false
      false
      true
      120000
      1800000
      false
      false
      1.0
      0



      DefaultDS
      org.jboss.pool.jdbc.xa.wrapper.XADataSourceImpl

      jdbc:HypersonicSQL:hsql://localhost:1476
      1200000
      sa
      10

      false
      false
      false
      true
      120000
      1800000
      false
      false
      1.0
      0


      <!-- Added for Informix -->


      InformixPool
      org.jboss.pool.jdbc.xa.wrapper.XADataSourceImpl

      jdbc:informix-sqli://10.220.10.16:3271/cmf:informixserver=gcdb_srv1;user=gcdbdev;password=gcdb.dev
      gcdbdev
      gcdb.dev


      <!-- End Add for Informix -->

      <!-- ==================================================================== -->
      <!-- JBoss Server Management -->
      <!-- ==================================================================== -->

      5000


      <!-- ==================================================================== -->
      <!-- J2EE deployment -->
      <!-- ==================================================================== -->


      true
      false
      false
      true
      false


      <!-- Uncomment to add embedded tomcat service

      -->

      <!-- Uncomment and set file URL to add Jetty service (you can set config more than once)

      file URL to jetty.xml e.g. file:/usr/local/jboss/dist/conf/default/jetty.xml

      -->


      <!-- ==================================================================== -->
      <!-- JBossMQ -->
      <!-- ==================================================================== -->


      <!-- The StateManager is used to keep JMS perisitent state data. -->
      <!-- For example: what durable subscriptions are active. -->

      jbossmq-state.xml


      <!-- The PersistenceManager is used to store messages to disk. -->

      ../../db/jbossmq/


      <!-- InvocationLayers are the different transport methods that can be used to access the server -->

      java:/ConnectionFactory
      java:/XAConnectionFactory



      RMIConnectionFactory
      RMIXAConnectionFactory



      ConnectionFactory
      XAConnectionFactory



      UILConnectionFactory
      UILXAConnectionFactory


      <!-- The following three line create 3 topics named: testTopic, example, and bob -->




      <!-- The following 9 line create 9 topics named: testQueue, controlQueue, A, B, -->
      <!-- C, D, E, F, and ex -->










      <!-- Used for backwards compatability with JBossMQ versions before 1.0.0 -->

      ConnectionFactory
      QueueConnectionFactory


      ConnectionFactory
      TopicConnectionFactory


      <!-- For Message Driven Beans -->

      DefaultJMSProvider
      org.jboss.jms.jndi.JBossMQProvider
      java:/XAConnectionFactory
      java:/XAConnectionFactory


      StdJMSPool
      org.jboss.jms.asf.StdServerSessionPoolFactory



      <!-- Make sure you change EmbeddedTomcat to Jetty if you are using Jetty -->

      Default
      :service=ContainerFactory
      :service=Jetty


      <!-- Uncomment this and disable previous J2eeDeployer entry to enable an alternative "scoped" deployment

      Default
      :service=ContainerFactory
      :service=Jetty

      -->

      <!-- ==================================================================== -->
      <!-- JBossCX setup, for J2EE connector architecture support -->
      <!-- ==================================================================== -->




      <!-- Minerva no transaction connection manager factory.

      Use this for resource adapters that don't support
      transactions. -->

      MinervaNoTransCMFactory

      org.jboss.pool.connector.jboss.MinervaNoTransCMFactory




      <!-- Minerva local transaction connection manager factory.

      Use this for resource adapters that support "local"
      transactions. -->

      MinervaSharedLocalCMFactory

      org.jboss.pool.connector.jboss.MinervaSharedLocalCMFactory




      <!-- Minerva XA transaction connection manager factory

      Use this for resource adapters that support "xa"
      transactions. -->

      MinervaXACMFactory

      org.jboss.pool.connector.jboss.MinervaXACMFactory




      <!-- Connection factory for the Minerva JDBC resource adapter. This
      points at the same database as DefaultDS. -->

      MinervaDS
      JCA:service=RARDeployer

      Minerva JDBC LocalTransaction ResourceAdapter


      ConnectionURL=jdbc:HypersonicSQL:hsql://localhost:1476



      MinervaSharedLocalCMFactory

      <!-- See the documentation for the specific connection manager
      implementation you are using for the properties you can set -->

      # Pool type - uncomment to force, otherwise it is the default
      #PoolConfiguration=per-factory

      # Connection pooling properties - see
      # org.jboss.pool.PoolParameters
      MinSize=0
      MaxSize=10
      Blocking=true
      GCEnabled=false
      IdleTimeoutEnabled=false
      InvalidateOnError=false
      TrackLastUsed=false
      GCIntervalMillis=120000
      GCMinIdleMillis=1200000
      IdleTimeoutMillis=1800000
      MaxIdleTimeoutPercent=1.0


      <!-- Principal mapping configuration -->

      org.jboss.resource.security.ManyToOnePrincipalMapping


      userName=sa
      password=



      <!-- This is an example of using a resource adapter that supports XA
      transactions. The Minerva XA resource adapter requires an
      XADataSource to be in JNDI somewhere. JBoss doesn't include a
      database with an XA-compliant JDBC driver, so this will need to
      be configured to use whatever XADataSource implementation you
      have.


      MinervaXADS

      Put your XADataSource implementation class here





      XAMinervaDS
      JCA:service=RARDeployer

      Minerva JDBA XA Resource Adapter


      XADataSourceName=java:/MinervaXADS



      MinervaXACMFactory


      # Pool type - uncomment to force, otherwise it is the default
      #PoolConfiguration=per-factory

      # Connection pooling properties - see
      # org.jboss.pool.PoolParameters
      MinSize=0
      MaxSize=10
      Blocking=true
      GCEnabled=false
      IdleTimeoutEnabled=false
      InvalidateOnError=false
      TrackLastUsed=false
      GCIntervalMillis=120000
      GCMinIdleMillis=1200000
      IdleTimeoutMillis=1800000
      MaxIdleTimeoutPercent=1.0



      org.jboss.resource.security.ManyToOnePrincipalMapping


      userName=sa
      password=


      -->

      <!-- JMS XA Resource adapter, use this to get transacted JMS in beans -->

      JmsXA
      JCA:service=RARDeployer
      JMS Adapter
      MinervaXACMFactory
      <!-- See the documentation for the specific connection manager
      implementation you are using for the properties you can set -->

      # Pool type - uncomment to force, otherwise it is the default
      #PoolConfiguration=per-factory

      # Connection pooling properties - see
      # org.jboss.pool.PoolParameters
      MinSize=0
      MaxSize=10
      Blocking=true
      GCEnabled=false
      IdleTimeoutEnabled=false
      InvalidateOnError=false
      TrackLastUsed=false
      GCIntervalMillis=120000
      GCMinIdleMillis=1200000
      IdleTimeoutMillis=1800000
      MaxIdleTimeoutPercent=1.0


      <!-- Principal mapping configuration -->
      org.jboss.resource.security.ManyToOnePrincipalMapping




      <!-- ==================================================================== -->
      <!-- Auto deployment -->
      <!-- ==================================================================== -->


      J2EE:service=J2eeDeployer;
      JCA:service=RARDeployer

      ../deploy,../deploy/lib


      <!-- ==================================================================== -->
      <!-- JMX adaptors -->
      <!-- ==================================================================== -->






      10

      8082


      <!-- ==================================================================== -->
      <!-- Mail Connection Factory -->
      <!-- ==================================================================== -->

      Mail
      mail.properties
      user_id
      password


      <!-- ==================================================================== -->
      <!-- Uncomment to enable JMX monitoring of the bean cache

      -->
      <!-- ==================================================================== -->

      <!-- ==================================================================== -->
      <!-- Scheduler Service -->
      <!-- ==================================================================== -->
      <!-- Uncomment this to enable Scheduling - ->











      <!- - -->

      <!-- ==================================================================== -->
      <!-- Add your custom MBeans here -->
      <!-- ==================================================================== -->



      ../../jetty
      file:../conf/jetty/jetty.xml
      ../../jetty/etc/webdefault.xml
      true
      true




      ******************************************************

        • 1. Re: Informix Distributed Transaction Problem with JBoss
          davidjencks

          Looking at your jboss.jcml, you are not using a resource adapter. If beans A and B are both using the informix database, you do not have a distributed transaction. Your XADataSourceLoader config looks ok to me.

          Are you sure it's a RuntimeException that is thrown? Can you provide more info on the context such as some code and a log excerpt? Is JBoss throwing a RemoteException of some kind?

          • 2. Re: Informix Distributed Transaction Problem with JBoss
            jbossravi

            I am throwing a runtime exception in bean A to test if the transaction gets rolled back. But the transaction is not rolling back. I am pasting the code for Bean A, Bean B and the client java application "Caller".

            ************************************************
            ************************************************
            Bean A

            public void ejbCreate() throws CreateException, RemoteException, EJBException {
            try
            {
            javax.naming.InitialContext ini = new javax.naming.InitialContext();
            ds = (javax.sql.DataSource) ini.lookup("java:/InformixPool");
            }
            catch(Exception e)
            {
            throw new RuntimeException();
            }
            }

            /**
            *
            * @ejbTransactionAttribute <bean default>
            * @associates <{Checkpoint}>
            */
            public void upload(String str) throws RemoteException, EJBException {
            java.sql.Statement stmt = null;
            java.sql.Connection conn = null;
            try
            {
            conn = ds.getConnection();
            stmt = conn.createStatement();
            stmt.executeUpdate("insert into tablenames values('" + str +"')");

            InitialContext jndiContext = new InitialContext();

            Object refb = jndiContext.lookup("BHomeBean");
            System.out.println("Got reference B");

            // Get a reference from this to the Bean's Home interface
            BHome homeb = (BHome)refb;
            BRemote b = homeb.create();
            System.out.println("upload b");
            b.upload("b");
            StringBuffer abc =null;
            abc.toString();

            }
            catch(Exception e)
            {
            ctx.setRollbackOnly();
            throw new RuntimeException();
            }
            finally
            {
            try
            {
            stmt.close();
            conn.close();
            }
            catch(Exception e)
            {
            throw new RuntimeException();
            }
            }
            }

            *******************************************************
            Bean B

            public void ejbCreate() throws CreateException, RemoteException, EJBException {
            try
            {
            javax.naming.InitialContext ini = new javax.naming.InitialContext();
            ds = (javax.sql.DataSource) ini.lookup("java:/InformixPool");
            }
            catch(Exception e)
            {
            throw new RuntimeException();
            }
            }

            /**
            *
            * @ejbTransactionAttribute <bean default>
            * @associates <{Checkpoint}>
            */
            public void upload(String str) throws RemoteException, EJBException {
            java.sql.Statement stmt = null;
            java.sql.Connection conn = null;
            try
            {
            conn = ds.getConnection();
            stmt = conn.createStatement();
            stmt.executeUpdate("insert into tablenames values('" + str +"')");
            throw new RuntimeException();
            }
            catch(Exception e)
            {
            throw new RuntimeException();
            }
            finally
            {
            try
            {
            stmt.close();
            conn.close();
            }
            catch(Exception e)
            {
            throw new RuntimeException();
            }
            }
            }

            *****************************************************
            Caller.java

            public static void main(String arg [])
            {
            try
            {
            java.util.Properties env = new java.util.Properties();
            env.setProperty(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
            env.setProperty(Context.PROVIDER_URL, "199.40.201.60:1099");
            env.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming");

            // Get a naming context
            InitialContext jndiContext = new InitialContext(env);
            System.out.println("Got context");

            Object ref = jndiContext.lookup("AHomeBean");
            System.out.println("Got reference A");

            // Get a reference from this to the Bean's Home interface
            AHome home = (AHome)ref;
            ARemote a = home.create();
            System.out.println("upload a");
            a.upload("a");
            /*
            Object refb = jndiContext.lookup("BHomeBean");
            System.out.println("Got reference B");

            // Get a reference from this to the Bean's Home interface
            BHome homeb = (BHome)refb;
            BRemote b = homeb.create();
            System.out.println("upload b");
            b.upload("b");
            */
            }
            catch(Exception ex)
            {
            ex.printStackTrace();
            }
            }
            **************************************************

            Here is the deployment descriptor

            <?xml version="1.0"?>
            <!DOCTYPE ejb-jar>
            <ejb-jar>
            <enterprise-beans>

            A Bean
            <ejb-name>AHomeBean</ejb-name>
            AHome
            ARemote
            <ejb-class>AImpl</ejb-class>
            <session-type>Stateless</session-type>
            <transaction-type>Container</transaction-type>


            B Bean
            <ejb-name>BHomeBean</ejb-name>
            BHome
            BRemote
            <ejb-class>BImpl</ejb-class>
            <session-type>Stateless</session-type>
            <transaction-type>Container</transaction-type>

            </enterprise-beans>
            <assembly-descriptor>
            <container-transaction>

            <ejb-name>AHomeBean</ejb-name>
            <method-name>*</method-name>

            <trans-attribute>Required</trans-attribute>
            </container-transaction>
            <container-transaction>

            <ejb-name>BHomeBean</ejb-name>
            <method-name>*</method-name>

            <trans-attribute>Required</trans-attribute>
            </container-transaction>
            </assembly-descriptor>
            </ejb-jar>
            ****************************************************
            ****************************************************

            • 3. Re: Informix Distributed Transaction Problem with JBoss
              jbossravi

              David!

              Is it because I am using a fake XA wrapper, that is the one supplied by JBoss. I read somewhere else your post that if one uses the fake driver, one might get 2 independent transactions rather than one xa transaction. That is what seems to be happening.

              • 4. Re: Informix Distributed Transaction Problem with JBoss
                sdhaene

                Your code was:

                public void ejbCreate() throws CreateException, RemoteException, EJBException {
                try
                {
                javax.naming.InitialContext ini = new javax.naming.InitialContext();
                ds = (javax.sql.DataSource) ini.lookup("java:/InformixPool");
                }
                catch(Exception e)
                {
                throw new RuntimeException();
                }
                }

                The problem is that, according to the EJB-spec, the ejbCreate() method is OUTSIDE of the transaction. Hence it can never be part of the transaction.
                See ejb-2_0-fr2-spec.pdf page 84 par. 7.7.3.
                You clearly see there that the transaction is started as you call the first business method. ejbCreate() is called BEFORE the first business method, and doesn't take part in the transaction.

                Hope this helps,

                Cheers,

                Stephan

                • 5. Re: Informix Distributed Transaction Problem with JBoss
                  sergioszy

                  You must upgrade to JBoss 2.4.4 and get the informix jdbc 2.2+ driver.
                  the datasource configuration for informix:

                  InformixDS
                  com.informix.jdbcx.IfxXADataSource

                  User=yournameuser
                  Password=yourpassword
                  PortNumber=1251
                  ServerName=supernova
                  DatabaseName=mydata
                  DataSourceName=InformixDS