*/
private static void morph(XADataSource xads) {
System.out.println("morph");
try {
XAConnection xac = xads.getXAConnection();
XAResource xar = xac.getXAResource();
Connection conn = xac.getConnection();
/*
autocommit off;
insert into foo values (1);
select * from global_xactTable where gxid is not null order by gxid,username;
commit;
*/
conn.setAutoCommit(false);
Statement s = conn.createStatement();
s.executeUpdate("insert into APP.foo values (2001)");
XATestUtil.showXATransactionView(conn);
conn.commit();
/*
autocommit on;
insert into foo values (2);
select * from global_xactTable where gxid is not null order by gxid,username;
*/
conn.setAutoCommit(true);
s.executeUpdate("insert into APP.foo values (2002)");
XATestUtil.showXATransactionView(conn);
/*
-- morph the connection to a global transaction
xa_start xa_noflags 1;
select * from global_xactTable where gxid is not null order by gxid,username;
insert into foo values (3);
*/
Xid xid = XATestUtil.getXid(1001, 66, 13);
xar.start(xid, XAResource.TMNOFLAGS);
XATestUtil.showXATransactionView(conn);
s.executeUpdate("insert into APP.foo values (2003)");
/*
-- disallowed
commit;
-- disallowed
rollback;
-- disallowed
autocommit on;
-- OK
autocommit off;
*/
try {
conn.commit();
System.out.println("FAIL: commit allowed in global xact");
} catch (SQLException e) {
}
try {
conn.rollback();
System.out.println("FAIL: roll back allowed in global xact");
} catch (SQLException e) {
}
try {
conn.setAutoCommit(true);
System.out
.println("FAIL: setAutoCommit(true) allowed "+
"in global xact");
} catch (SQLException e) {
}
try {
conn.setSavepoint();
System.out
.println("FAIL: setSavepoint() allowed in global xact");
} catch (SQLException e) {}
try {
conn.setSavepoint("badsavepoint");
System.out
.println("FAIL: setAutoCommit(String) allowed in "+
"global xact");
} catch (SQLException e) {}
conn.setAutoCommit(false);
// s was created in local mode so it has holdibilty
// set, will execute but ResultSet will have close on commit
if (TestUtil.isDerbyNetClientFramework()) { // DERBY-1158
s.executeQuery("select * from APP.foo where A >= 2000").close();
System.out.println("OK: query with holdable statement");
}
s.close();
s = conn.createStatement();
boolean holdable = s.getResultSetHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT;
System.out.println("Statement created in global has holdabilty: "
+ holdable);
/*
select * from foo;
xa_end xa_success 1;
xa_prepare 1;
*/
ResultSet rs = s
.executeQuery("select * from APP.foo where A >= 2000");
JDBCDisplayUtil.DisplayResults(System.out, rs, conn);
rs.close();
xar.end(xid, XAResource.TMSUCCESS);
xar.prepare(xid);
/*
-- dup id
xa_start xa_noflags 1;
*/
try {
xar.start(xid, XAResource.TMNOFLAGS);
System.out.println("FAIL - start with duplicate XID");
} catch (XAException e) {
if (e.errorCode != XAException.XAER_DUPID)
throw e;
}
/*
xa_start xa_noflags 2;
-- still should disallow autommit;
autocommit on;
-- still should disallow commit and rollback
commit;
rollback;
select * from global_xactTable where gxid is not null order by gxid,username;
xa_end xa_suspend 2;
*/
Xid xid2 = XATestUtil.getXid(1002, 23, 3);
xar.start(xid2, XAResource.TMNOFLAGS);
try {
conn.commit();
System.out.println("FAIL: commit allowed in global xact");
} catch (SQLException e) {
}
try {
conn.rollback();
System.out.println("FAIL: roll back allowed in global xact");
} catch (SQLException e) {
}
try {
conn.setAutoCommit(true);
System.out
.println("FAIL: setAutoCommit(true) allowed in global xact");
} catch (SQLException e) {
}
conn.setAutoCommit(false);
xar.end(xid2, XAResource.TMSUSPEND);
/*
-- get local connection again
xa_getconnection;
insert into foo values (5);
-- autocommit should be on by default;
commit;
autocommit off;
insert into foo values (6);
-- commit and rollback is allowed on local connection
rollback;
insert into foo values (6);
commit;
*/
conn = xac.getConnection();
s = conn.createStatement();
s.executeUpdate("insert into APP.foo values (2005)");
conn.commit();
conn.setAutoCommit(false);
s.executeUpdate("insert into APP.foo values (2006)");
conn.rollback();
s.executeUpdate("insert into APP.foo values (2007)");
conn.commit();
XATestUtil.showXATransactionView(conn);
/*
-- I am still able to commit other global transactions while I am attached to a
-- local transaction.
xa_commit xa_2phase 1;
xa_end xa_success 2;
xa_rollback 2;
*/
xar.commit(xid, false);
xar.end(xid2, XAResource.TMSUCCESS);
xar.rollback(xid2);
XATestUtil.showXATransactionView(conn);
rs = s.executeQuery("select * from APP.foo where A >= 2000");
JDBCDisplayUtil.DisplayResults(System.out, rs, conn);
rs.close();
conn.close();
/*
xa_getconnection;
select * from global_xactTable where gxid is not null order by gxid,username;
select * from foo;
autocommit off;
delete from foo;
*/
conn = xac.getConnection();
conn.setAutoCommit(false);
s = conn.createStatement();
s.executeUpdate("delete from app.foo");
rs = s.executeQuery("select * from APP.foo");
JDBCDisplayUtil.DisplayResults(System.out, rs, conn);
rs.close();
// DERBY-1004
if (TestUtil.isDerbyNetClientFramework()) {
System.out.println("DERBY-1004 Call conn.rollback to avoid exception with client");
conn.rollback();
}
/*
-- yanking a local connection away should rollback the changes
*/
conn = xac.getConnection();
conn.setAutoCommit(false);
s = conn.createStatement();
rs = s.executeQuery("select * from APP.foo where A >= 2000");
JDBCDisplayUtil.DisplayResults(System.out, rs, conn);
rs.close();
/*
-- cannot morph it if the local transaction is not idle
xa_start xa_noflags 3;
commit;
-- now morph it to a global transaction
xa_start xa_noflags 3;
*/
Xid xid3 = XATestUtil.getXid(1003, 27, 9);
try {
xar.start(xid3, XAResource.TMNOFLAGS);
System.out.println("FAIL XAResource.start on a global transaction with an active local transaction (autocommit false)");
} catch (XAException xae) {
if (xae.errorCode != XAException.XAER_OUTSIDE)
throw xae;
System.out.println("Correct XAException on starting a global transaction with an active local transaction (autocommit false)");
}
conn.commit();
xar.start(xid3, XAResource.TMNOFLAGS);
/*
-- now I shouldn't be able to yank it
xa_getconnection;
*/
if (TestUtil.isDerbyNetClientFramework()) {
System.out.println("DERBY-341 - Client skipping XAConnection with active local transaction");
} else {
try {
xac.getConnection();
System.out
.println("FAIL: getConnection with active global xact");
} catch (SQLException sqle) {
TestUtil.dumpSQLExceptions(sqle, true);
}
}
/*
select * from foo;
delete from foo;
xa_end xa_fail 3;
xa_rollback 3;
-- local connection again
xa_getconnection;
select * from global_xactTable where gxid is not null order by gxid,username;
select * from foo;
*/
s = conn.createStatement();
s.executeUpdate("delete from APP.foo");
rs = s.executeQuery("select * from APP.foo where A >= 2000");
JDBCDisplayUtil.DisplayResults(System.out, rs, conn);
rs.close();
try {
xar.end(xid3, XAResource.TMFAIL);
} catch (XAException e) {
if (e.errorCode != XAException.XA_RBROLLBACK)
throw e;
}
xar.rollback(xid3);
conn = xac.getConnection();
s = conn.createStatement();
rs = s.executeQuery("select * from APP.foo where A >= 2000");
JDBCDisplayUtil.DisplayResults(System.out, rs, conn);
rs.close();