1 Reply Latest reply on Apr 26, 2010 11:31 PM by vickyk

    AS400JDBCXADataSource - getting started with two txns

      Hi,

       

      I am trying to get started with XA using JBOSS connected to two datasources (seperate applications) on the same AS400 (DB2) database.

       

      I have two datasources (see attached) and have the following code...

      UserTransaction utx;

       

      InitialContext initialContext = EquationCommonContext.getContext().getNamingInitialContext();

       

      try

      {

      utx = (UserTransaction) initialContext.lookup("UserTransaction");

      DataSource dataSource1 = (DataSource) initialContext.lookup("EQ-EQ4");

      DataSource dataSource2 = (DataSource) initialContext.lookup("EQ-EQ5");

       

       

      // begin a trannie

      utx.begin();

       

       

      // ..

      Connection connection1 = dataSource1.getConnection();

      Statement statement1 = connection1.createStatement();

      statement1.execute(

      "INSERT INTO KFILEQ4/JVPF (JVHRC, JVHRD) VALUES('E01', 'EEE')");

      statement1.close();

      connection1.close();

       

      Connection connection2 = dataSource2.getConnection();

      Statement statement2 = connection2.createStatement();

      statement2.execute(

      "INSERT INTO KFILEQ4/JVPF (JVHRC, JVHRD) VALUES('E02', 'EEE')");

      statement2.close();

      connection2.close();

       

       

      // unfortunatelt the following line fails

      utx.commit();

      System.out.println(utx.getStatus());

      }

       

       

      catch (Exception e)

      {

      e.printStackTrace();

      }

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

      unfortunately I get the following error when i execute the commit....

       

       

      14:53:50,076 INFO [STDOUT] Wed Apr 14 14:53:50:076 BST 2010 as400: XAResource B603382C-XA:RMID#49153 (30120272) : xa_end.

      14:53:50,076 INFO [STDOUT] Wed Apr 14 14:53:50:076 BST 2010 as400: XAResource B603382C-XA:RMID#49153 (30120272) : xa error class = 0, return code = 0.

      14:53:50,076 INFO [STDOUT] Wed Apr 14 14:53:50:076 BST 2010 as400: XAResource B603382C-XA:RMID#49153 (30120272) : xa_commit.

      14:53:50,092 INFO [STDOUT] Wed Apr 14 14:53:50:092 BST 2010 as400: XAResource B603382C-XA:RMID#49153 (30120272) : xa error class = 9, return code = -6.

      14:53:50,092 ERROR [STDERR]

      javax.transaction.RollbackException: [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] Could not commit transaction.

      14:53:50,092 ERROR [STDERR] at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(

      TransactionImple.java:1426)

      14:53:50,092 ERROR [STDERR] at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(

      BaseTransaction.java:135)

      14:53:50,092 ERROR [STDERR] at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(

      BaseTransactionManagerDelegate.java:75)

      14:53:50,092 ERROR [STDERR] at org.jboss.tm.usertx.client.ServerVMClientUserTransaction.commit(

      ServerVMClientUserTransaction.java:162)

      14:53:50,092 ERROR [STDERR] at com.misys.equation.ui.services.ServiceDirectory.startXATransaction(

      ServiceDirectory.java:1156)

      14:53:50,092 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke0(

      Native Method)

      14:53:50,092 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

      14:53:50,092 ERROR [STDERR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

      14:53:50,092 ERROR [STDERR] at java.lang.reflect.Method.invoke(Unknown Source)

      14:53:50,092 ERROR [STDERR] at org.apache.axis.providers.java.RPCProvider.invokeMethod(

      RPCProvider.java:397)

      14:53:50,092 ERROR [STDERR] at org.apache.axis.providers.java.RPCProvider.processMessage(

      RPCProvider.java:186)

      14:53:50,092 ERROR [STDERR] at org.apache.axis.providers.java.JavaProvider.invoke(

      JavaProvider.java:323)

      14:53:50,092 ERROR [STDERR] at org.apache.axis.strategies.InvocationStrategy.visit(

      InvocationStrategy.java:32)

      14:53:50,092 ERROR [STDERR] at org.apache.axis.SimpleChain.doVisiting(

      SimpleChain.java:118)

      14:53:50,092 ERROR [STDERR] at org.apache.axis.SimpleChain.invoke(

      SimpleChain.java:83)

      14:53:50,092 ERROR [STDERR] at org.apache.axis.handlers.soap.SOAPService.invoke(

      SOAPService.java:454)

      14:53:50,092 ERROR [STDERR] at org.apache.axis.server.AxisServer.invoke(

      AxisServer.java:281)

      14:53:50,092 ERROR [STDERR] at org.apache.axis.transport.http.AxisServlet.doPost(

      AxisServlet.java:699)

      14:53:50,092 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(

      HttpServlet.java:637)

      14:53:50,092 ERROR [STDERR] at org.apache.axis.transport.http.AxisServletBase.service(

      AxisServletBase.java:327)

      14:53:50,092 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(

      HttpServlet.java:717)

      14:53:50,092 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(

      ApplicationFilterChain.java:290)

      14:53:50,092 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(

      ApplicationFilterChain.java:206)

      14:53:50,092 ERROR [STDERR] at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(

      ReplyHeaderFilter.java:96)

      14:53:50,092 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(

      ApplicationFilterChain.java:235)

      14:53:50,092 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(

      ApplicationFilterChain.java:206)

      14:53:50,092 ERROR [STDERR] at org.apache.catalina.core.StandardWrapperValve.invoke(

      StandardWrapperValve.java:235)

      14:53:50,092 ERROR [STDERR] at org.apache.catalina.core.StandardContextValve.invoke(

      StandardContextValve.java:191)

      14:53:50,092 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(

      SecurityAssociationValve.java:190)

      14:53:50,092 ERROR [STDERR] at org.jboss.web.tomcat.security.JaccContextValve.invoke(

      JaccContextValve.java:92)

      14:53:50,092 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(

      SecurityContextEstablishmentValve.java:126)

      14:53:50,092 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(

      SecurityContextEstablishmentValve.java:70)

      14:53:50,092 ERROR [STDERR] at org.apache.catalina.core.StandardHostValve.invoke(

      StandardHostValve.java:127)

      14:53:50,092 ERROR [STDERR] at org.apache.catalina.valves.ErrorReportValve.invoke(

      ErrorReportValve.java:102)

      14:53:50,092 ERROR [STDERR] at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(

      CachedConnectionValve.java:158)

      14:53:50,092 ERROR [STDERR] at org.apache.catalina.core.StandardEngineValve.invoke(

      StandardEngineValve.java:109)

      14:53:50,092 ERROR [STDERR] at org.apache.catalina.connector.CoyoteAdapter.service(

      CoyoteAdapter.java:330)

      14:53:50,092 ERROR [STDERR] at org.apache.coyote.http11.Http11Processor.process(

      Http11Processor.java:829)

      14:53:50,092 ERROR [STDERR] at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(

      Http11Protocol.java:601)

      14:53:50,092 ERROR [STDERR] at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(

      JIoEndpoint.java:447)

      14:53:50,092 ERROR [STDERR] at java.lang.Thread.run(Unknown Source)

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

       


      Now when i run the following code I don't get a problem....

       

      package com.misys.equation.common.test.connectivity;

      import java.io.Serializable;
      import java.sql.Connection;
      import java.sql.SQLException;
      import java.sql.Statement;
      import java.util.Arrays;
      import java.util.Random;

      import javax.sql.XAConnection;
      import javax.transaction.xa.XAException;
      import javax.transaction.xa.XAResource;
      import javax.transaction.xa.Xid;

      import com.ibm.as400.access.AS400JDBCXADataSource;
      import com.ibm.as400.access.AS400JDBCXAResource;
      import com.misys.equation.common.utilities.Toolbox;

      public class XATest
      {
      // This attribute is used to store cvs version information.
      public static final String _revision = "$Id: FileProcessor.java,v 1.6 2009/09/16 16:13:27 esther.williams Exp $";
      String user1 = "whatever";
      String password1 = "itmaybe";
      String system1 = "machineA";
      String user2 = "whatever";
      String password2 = "itmaybe";
      String system2 = "machineA";
      String library = "*LIBL";
      AS400JDBCXADataSource xaDataSource1 = null;
      XAConnection xaConnection1 = null;
      XAResource xaResource1 = null;
      XidImpl xid = null;
      Connection connection1 = null;
      Statement statement1 = null;
      AS400JDBCXADataSource xaDataSource2 = null;
      XAConnection xaConnection2 = null;
      XAResource xaResource2 = null;
      AS400JDBCXAResource a;
      // XidImpl xid2 = null;
      Connection connection2 = null;
      Statement statement2 = null;

      private XATest()
      {
      }

      public static void main(String[] args)
      {
        System.out.println("Proceeding with test...");
        XATest test = new XATest();
        test.test();
      }

      private void test()
      {
        try
        {
         xaDataSource1 = new AS400JDBCXADataSource();
         xaDataSource1.setServerName(system1);
         xaDataSource1.setUser(user1);
         xaDataSource1.setPassword(password1);
         xaDataSource1.setLibraries(library);
         xaDataSource1.setNaming("system");
         xaDataSource1.setTranslateBinary(false);
         xaDataSource1.setTrace(true);

         xaDataSource2 = new AS400JDBCXADataSource();
         xaDataSource2.setServerName(system2);
         xaDataSource2.setUser(user2);
         xaDataSource2.setPassword(password2);
         xaDataSource2.setLibraries(library);
         xaDataSource2.setNaming("system");
         xaDataSource2.setTranslateBinary(false);
         xaDataSource2.setTrace(true);

         xaConnection1 = xaDataSource1.getXAConnection();
         xaConnection2 = xaDataSource2.getXAConnection();

         xaResource1 = xaConnection1.getXAResource();
         xaResource2 = xaConnection2.getXAResource();

         xid = new XidImpl(new byte[] { 0x0d }, new byte[] { 0x0b });

         xaResource1.start(xid, XAResource.TMNOFLAGS);

         // Need to decide whether to join based on whether the resources have the same resource manager
         // if the are the same then the prepares, commits and rollbacks should only be executed on
         // the first resource
         if (xaResource1.isSameRM(xaResource2))
         {
          xaResource2.start(xid, XAResource.TMJOIN);
         }
         else
         {
          xaResource2.start(xid, XAResource.TMNOFLAGS);
         }

         // Do some SQL on connection 1
         connection1 = xaConnection1.getConnection();
         statement1 = connection1.createStatement();
         statement1.executeUpdate("INSERT INTO KFILEQ4/JVPF (JVHRC, JVHRD) VALUES('X01', 'X01D')");

         // Do some SQL on connection 2
         connection2 = xaConnection2.getConnection();
         statement2 = connection2.createStatement();
         statement2.executeUpdate("INSERT INTO KFILEQ4/JVPF (JVHRC, JVHRD) VALUES('X02', 'X02D')");

         // tell the resources that we have successfully finished doing the work,
         // need to consider what to do if the SQL had gone wrong!
         xaResource1.end(xid, XAResource.TMSUCCESS);
         xaResource2.end(xid, XAResource.TMSUCCESS);

         if (xaResource1.isSameRM(xaResource2))
         {
          // only need to prepare on the first resource
          int ret1 = xaResource1.prepare(xid);
          // int ret2 = xaResource2.prepare(xid);
         
          // only need to commit on the first resource
          xaResource1.commit(xid, false);
          // xaResource2.commit(xid, false);
         }
         else
         {
          int ret1 = xaResource1.prepare(xid);
          int ret2 = xaResource2.prepare(xid);
          xaResource1.commit(xid, false);
          xaResource2.commit(xid, false);
         }
        }
        catch (XAException e)
        {
         e.printStackTrace();
        }
        catch (SQLException e)
        {
         e.printStackTrace();
        }
        finally
        {
         try
         {
          statement1.close();
          statement2.close();
          connection1.close();
          connection2.close();
          xaConnection1.close();
          xaConnection2.close();
         }
         catch (Exception e2)
         {
          // TODO: handle exception
         }
        }
      }
      public static class XidImpl implements Serializable, Xid
      {
        private static final long serialVersionUID = 1L;
        private static Random random = new Random();
        private final int formatId = 876;
        private final byte[] globalTransactionId;
        private final byte[] branchQualifier;
        private transient String cachedToString;
        private transient int cachedHashCode;

        public XidImpl()
        {
         globalTransactionId = new byte[10];
         random.nextBytes(globalTransactionId);
         branchQualifier = new byte[10];
         random.nextBytes(branchQualifier);
        }
        public XidImpl(byte[] globalTransactionId, byte[] branchQualifier)
        {
         this.globalTransactionId = globalTransactionId;
         this.branchQualifier = branchQualifier;
        }

        public int getFormatId()
        {
         return formatId;
        }

        public byte[] getGlobalTransactionId()
        {
         return globalTransactionId;
        }

        public byte[] getBranchQualifier()
        {
         return branchQualifier;
        }

        @Override
        public boolean equals(Object object)
        {
         if (object == this)
          return true;
         if (object == null || object instanceof Xid == false)
          return false;

         Xid other = (Xid) object;
         return (formatId == other.getFormatId() && Arrays.equals(globalTransactionId, other.getGlobalTransactionId()) && Arrays
             .equals(branchQualifier, other.getBranchQualifier()));
        }

        @Override
        public int hashCode()
        {
         if (cachedHashCode == 0)
         {
          cachedHashCode = formatId;
          for (int j = 0; j < globalTransactionId.length; ++j)
           cachedHashCode += globalTransactionId[j];
         }
         return cachedHashCode;
        }

        @Override
        public String toString()
        {
         if (cachedToString == null)
         {
          StringBuffer buffer = new StringBuffer();
          buffer.append("XidImpl[FormatId=").append(getFormatId());
          buffer.append(" GlobalId=x'").append(Toolbox.cvtBytesToHexString(getGlobalTransactionId()));
          buffer.append("' BranchQual=x'").append(Toolbox.cvtBytesToHexString(getBranchQualifier()));
          buffer.append("']");
          cachedToString = buffer.toString();
         }
         return cachedToString;
        }
      }
      }

       

      Note there is an extra "end" for the secound resource and a "prepare" that i don't see logged in the jboss example.

       

      Any ideas?