AS400JDBCXADataSource - getting started with two txns
weddelc1 Apr 14, 2010 10:20 AMHi,
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?
-
eq-EQ5-xa-ds.xml 1.3 KB
-
eq-EQ4-xa-ds.xml 1.3 KB