Community

AS400JDBCDataSource - getting started with two transactions

created by Esther Williams in JCA - View the full discussion

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>

 

Reply to this message by going to Community

Start a new discussion in JCA at Community