0 Replies Latest reply on May 11, 2010 2:05 PM by esther_williams

    AS400JDBCDataSource - getting started with two transactions

      Hi,

       

      This is the discussion started by Chris Weddell but hopefully without formatting issues.

       

      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 below) and have the following code...

      package

       

       

       

       

       

       

       

      com.misys.equation.xa.test;

       

      import

       

       

       

       

       

       

       

      java.sql.Connection;

      import

       

       

       

       

       

       

       

      java.sql.Statement;

       

      import

       

       

       

       

       

       

       

      javax.naming.InitialContext;

      import

       

       

       

       

       

       

       

      javax.sql.DataSource;

      import

       

       

       

       

       

       

       

      javax.transaction.UserTransaction;

       

      public

       

       

       

       

       

       

       

      class Esther

      {

       

       

      public static void main(String[] args)

      {

      UserTransaction utx;

       

       

      try

      {

      InitialContext initialContext =

       

       

      new InitialContext();

       

      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();

       

       

      // unfortunately 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 http://community.jboss.org/message/537429#537429/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.xa.test;

       

      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 Esther2

      {

       

       

      // 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;

       

       

      // private XidImpl xid2 = null;

      Connection

       

       

      connection2 = null;

      Statement

       

      statement2 = null;

       

       

       

      private Esther2()

      {

      }

       

       

       

      public static void main(String[] args)

      {

      System.

       

      out.println("Proceeding with test...");

      Esther2 test =

       

      new Esther2();

      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?

       

      <?xml version="1.0" encoding="UTF-8" ?>

      - <datasources>
      - <xa-datasource>
      <jndi-name>EQ-EQ5</jndi-name>
      <use-java-context>false</use-java-context>
      <xa-datasource-class>com.ibm.as400.access.AS400JDBCXADataSource</xa-datasource-class>
      <xa-datasource-property name="User">WHATEVER</xa-datasource-property>
      <xa-datasource-property name="Password">ITMAYBE</xa-datasource-property>
      <xa-datasource-property name="ServerName">MACHINEA</xa-datasource-property>
      <xa-datasource-property name="Libraries">*LIBL</xa-datasource-property>
      <xa-datasource-property name="Naming">system</xa-datasource-property>
      <track-connection-by-tx>true</track-connection-by-tx>
      <prepared-statement-cache-size>100</prepared-statement-cache-size>
      <isSameRM-override-value>false</isSameRM-override-value>
      <no-tx-separate-pools />
      <new-connection-sql />
      <check-valid-connection-sql />
      <!--
      pooling parameters
      -->
      <min-pool-size>1</min-pool-size>
      <max-pool-size>50</max-pool-size>
      <blocking-timeout-millis>50000</blocking-timeout-millis>
      <idle-timeout-minutes>5</idle-timeout-minutes>
      - <metadata>
      <type-mapping>DB2/400</type-mapping>
      </metadata>
      </xa-datasource>
      </datasources>

       

      <?xml version="1.0" encoding="UTF-8" ?>
      - <datasources>
      - <xa-datasource>
      <jndi-name>EQ-EQ4</jndi-name>
      <use-java-context>false</use-java-context>
      <xa-datasource-class>com.ibm.as400.access.AS400JDBCXADataSource</xa-datasource-class>
      <xa-datasource-property name="User">WHATEVER</xa-datasource-property>
      <xa-datasource-property name="Password">ITMAYBE</xa-datasource-property>
      <xa-datasource-property name="ServerName">MACHINEA</xa-datasource-property>
      <xa-datasource-property name="Libraries">*LIBL</xa-datasource-property>
      <xa-datasource-property name="Naming">system</xa-datasource-property>
      <track-connection-by-tx>true</track-connection-by-tx>
      <prepared-statement-cache-size>100</prepared-statement-cache-size>
      <isSameRM-override-value>false</isSameRM-override-value>
      <no-tx-separate-pools />
      <new-connection-sql />
      <check-valid-connection-sql />
      <!--
      pooling parameters
      -->
      <min-pool-size>1</min-pool-size>
      <max-pool-size>50</max-pool-size>
      <blocking-timeout-millis>50000</blocking-timeout-millis>
      <idle-timeout-minutes>5</idle-timeout-minutes>
      - <metadata>
      <type-mapping>DB2/400</type-mapping>
      </metadata>
      </xa-datasource>
      </datasources>