int[] CallableStatementExpectedValues = {
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY,
ResultSet.FETCH_REVERSE, 999, 137, 85,
ResultSet.HOLD_CURSORS_OVER_COMMIT};
XADataSource dsx = J2EEDataSource.getXADataSource();
XAConnection xac = dsx.getXAConnection();
AssertEventCatcher aes6 = new AssertEventCatcher(6);
xac.addConnectionEventListener(aes6);
XAResource xar = xac.getXAResource();
Xid xid = new cdsXid(1, (byte) 103, (byte) 119);
// now check re-use of *Statement objects across local/global
// connections.
Connection cs1 = xac.getConnection();
// ensure read locks stay around until end-of transaction
cs1.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
cs1.setAutoCommit(false);
assertLocks(null, cs1);
Statement sru1 = cs1.createStatement();
sru1.setCursorName("SN1");
sru1.executeUpdate("insert into intTable values 1,2,3");
Statement sruBatch = cs1.createStatement();
sruBatch.setCursorName("sruBatch");
Statement sruState = createFloatStatementForStateChecking(
StatementExpectedValues, cs1);
PreparedStatement psruState = createFloatStatementForStateChecking(
new int[] {1, 4}, PreparedStatementExpectedValues, cs1,
"select i from intTable where i = ?");
CallableStatement csruState = createFloatCallForStateChecking(
new int[] {2, 12, 12}, CallableStatementExpectedValues, cs1,
"CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(?,?)");
PreparedStatement psParams =
cs1.prepareStatement("select * from intTable where i > ?");
psParams.setCursorName("params");
psParams.setInt(1, 2);
// Params-local-1
resultSetQuery("params", three, psParams.executeQuery());
sruBatch.addBatch("insert into intTable values 4");
// sru1-local-1
queryOnStatement("SN1", onetwothree, cs1, sru1);
cs1.commit(); // need to commit to switch to an global connection;
// simple case - underlying connection is re-used for global.
xar.start(xid, XAResource.TMNOFLAGS);
// Expecting downgrade because global transaction sru1-global-2 is
// using a statement with holdability true
// sru1-global-2
queryOnStatement("SN1", onetwothree, cs1, sru1);
sruBatch.addBatch("insert into intTable values 5");
Statement sru2 = cs1.createStatement();
sru2.setCursorName("OAK2");
//sru2-global-3
queryOnStatement("OAK2", onetwothree, cs1, sru2);
// Expecting downgrade because global transaction sru1-global-4 is
// using a statement with holdability true
// sru1-global-4
queryOnStatement("SN1", onetwothree, cs1, sru1);
// Global statement
StatementExpectedValues[6] = ResultSet.CLOSE_CURSORS_AT_COMMIT;
PreparedStatementExpectedValues[6] = ResultSet.CLOSE_CURSORS_AT_COMMIT;
CallableStatementExpectedValues[6] = ResultSet.CLOSE_CURSORS_AT_COMMIT;
assertStatementState(null, StatementExpectedValues ,sruState);
// Global PreparedStatement
assertStatementState(pspc, PreparedStatementExpectedValues, psruState);
// Global CallableStatement
assertStatementState(cspc, CallableStatementExpectedValues, csruState);
// Params-global-1
resultSetQuery("params", three, psParams.executeQuery());
xar.end(xid, XAResource.TMSUCCESS);
// now a new underlying connection is created
// sru1-local-5
queryOnStatement("SN1", onetwothree, cs1, sru1);
// sru2-local-6
queryOnStatement("OAK2", onetwothree, cs1, sru2);
sruBatch.addBatch("insert into intTable values 6,7");
Statement sru3 = cs1.createStatement();
sru3.setCursorName("SF3");
// sru3-local-7
queryOnStatement("SF3", onetwothree, cs1, sru3);
// Two transactions should hold locks (global and the current XA);
// LOCAL
StatementExpectedValues[6] = ResultSet.HOLD_CURSORS_OVER_COMMIT;
PreparedStatementExpectedValues[6] = ResultSet.HOLD_CURSORS_OVER_COMMIT;
CallableStatementExpectedValues[6] = ResultSet.HOLD_CURSORS_OVER_COMMIT;
assertStatementState(null, StatementExpectedValues, sruState);
assertStatementState(pspc, PreparedStatementExpectedValues, psruState);
assertStatementState(cspc, CallableStatementExpectedValues, csruState);
// Params-local-2
resultSetQuery("params", three, psParams.executeQuery());
assertLocks(new int[] {14,14}, cs1);
cs1.commit();
//Confirm - no connection closed event & connection error event
assertFalse(aes6.didConnectionClosedEventHappen());
assertFalse(aes6.didConnectionErrorEventHappen());
aes6.resetState();
// attach the XA transaction to another connection and see what happens
XAConnection xac2 = dsx.getXAConnection();
AssertEventCatcher aes5 = new AssertEventCatcher(5);
xac2.addConnectionEventListener(aes5);
XAResource xar2 = xac2.getXAResource();
xar2.start(xid, XAResource.TMJOIN);