📄 xatest.java
字号:
/* Derby - Class org.apache.derby.impl.services.bytecode.CodeChunk Copyright 2006 The Apache Software Foundation or its licensors, as applicable. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */package org.apache.derbyTesting.functionTests.tests.jdbcapi;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.SQLWarning;import java.sql.Statement;import java.util.ArrayList;import java.util.Iterator;import java.util.Properties;import javax.sql.XAConnection;import javax.sql.XADataSource;import javax.transaction.xa.XAException;import javax.transaction.xa.XAResource;import javax.transaction.xa.Xid;import org.apache.derby.tools.JDBCDisplayUtil;import org.apache.derby.tools.ij;import org.apache.derbyTesting.functionTests.util.TestUtil;import org.apache.derbyTesting.functionTests.util.XATestUtil;/** * XATests harvested from SQL XA tests. * Modified so that they can be run with NetworkServer. */public class XATest { /** * Run all the tests. */ public static void main(String[] args) throws Exception { ij.getPropertyArg(args); Connection dmc = ij.startJBMS(); showHoldStatus("initial ", dmc); XATestUtil.createXATransactionView(dmc); dmc.close(); XADataSource dsx = TestUtil.getXADataSource(cleanProperties()); // tests originally from xaSimplePositive.sql singleConnectionOnePhaseCommit(dsx); xaShutdown(); interleavingTransactions(dsx); xaShutdown(); // tests originally from xaStateTran.sql noTransaction(dsx); // test originally from xaMorph.sql morph(dsx); // DERBY-966 holdability testing derby966(dsx); System.out.println("XATest complete"); } /** * Get the basic set of properties for an XADataSource. * Only sets databaseName to wombat. * @return */ private static Properties cleanProperties() { Properties dsAttrs = new Properties(); dsAttrs.setProperty("databaseName", "wombat"); return dsAttrs; } /** * Shutdown the database through an XADataSource. */ private static void xaShutdown() { Properties dsAttrs = cleanProperties(); if (TestUtil.isEmbeddedFramework()) dsAttrs.put("shutdownDatabase", "shutdown"); else dsAttrs.put("connectionAttributes", "shutdown=true"); XADataSource dsx = TestUtil.getXADataSource(dsAttrs); try { dsx.getXAConnection().getConnection(); } catch (SQLException sqle) { if ("08006".equals(sqle.getSQLState())) return; TestUtil.dumpSQLExceptions(sqle); } System.out.println("FAIL: no exception on shutdown"); } /* ** Test cases */ /** * A single connection and 1 phase commit. * Original "SQL" from xaSimplePositive.sql <code> xa_connect ; xa_start xa_noflags 0; xa_getconnection; drop table foo; create table foo (a int); insert into foo values (0); select * from foo; run resource '/org/apache/derbyTesting/functionTests/tests/store/global_xactTable.view'; select * from global_xactTable where gxid is not null order by gxid; xa_end xa_success 0; xa_commit xa_1phase 0; xa_datasource 'wombat' shutdown; </code> * @throws SQLException * @throws XAException */ private static void singleConnectionOnePhaseCommit(XADataSource xads) { System.out.println("singleConnectionOnePhaseCommit"); try { XAConnection xac = xads.getXAConnection(); XAResource xar = xac.getXAResource(); Xid xid = XATestUtil.getXid(0, 32, 46); xar.start(xid, XAResource.TMNOFLAGS); Connection conn = xac.getConnection(); showHoldStatus("XA ", conn); Statement s = conn.createStatement(); showHoldStatus("XA ", s); s.execute("create table foo (a int)"); s.executeUpdate("insert into foo values (0)"); ResultSet rs = s.executeQuery("select * from foo"); JDBCDisplayUtil.DisplayResults(System.out, rs, conn); rs.close(); XATestUtil.showXATransactionView(conn); s.close(); xar.end(xid, XAResource.TMSUCCESS); // 1 phase commit xar.commit(xid, true); conn.close(); xac.close(); } catch (SQLException sqle) { TestUtil.dumpSQLExceptions(sqle); sqle.printStackTrace(System.out); } catch (XAException e) { XATestUtil.dumpXAException("singleConnectionOnePhaseCommit", e); } } /* * Two interleaving transaction and prepare/commit prepare/rollback. * * (original test said two connections but only one connection was opened) <code> xa_datasource 'wombat'; xa_connect user 'sku' password 'testxa' ; xa_start xa_noflags 1; xa_getconnection; insert into APP.foo values (1); xa_end xa_suspend 1; xa_start xa_noflags 2; insert into APP.foo values (2); xa_end xa_suspend 2; xa_start xa_resume 1; insert into APP.foo values (3); xa_end xa_suspend 1; xa_start xa_resume 2; insert into APP.foo values (4); select * from APP.global_xactTable where gxid is not null order by gxid; -- this prepare won't work since transaction 1 has been suspended - XA_PROTO xa_prepare 1; select * from APP.global_xactTable where gxid is not null order by gxid; xa_end xa_success 2; -- this assumes a resume xa_end xa_success 1; xa_prepare 1; xa_prepare 2; -- both transactions should be prepared select * from APP.global_xactTable where gxid is not null order by gxid; -- NOTE: The following call to "xa_recover xa_startrscan" is apt to -- return the result set rows in reverse order when changes to -- the Derby engine affect the number of transactions that it takes -- to create a database. The transactions are stored in a hash table -- based on a global and local id, and when the number of transactions -- changes, the (internal) local id can change, which may lead to a -- change in the result set order. This order is determined by the -- JVM's hashing algorithm. Examples of changes to the engine that -- can affect this include ones that cause more commits or that -- change the amount of data being stored, such as changes to the -- metadata statements (which is what prompted this explanation in -- the first place). Ultimately, the problem is that there is no -- way to order the return values from "xa_recover" since it is an -- ij internal statement, not SQL... xa_recover xa_startrscan; xa_recover xa_noflags; xa_commit xa_2Phase 1; xa_rollback 2; -- check results xa_start xa_noflags 3; select * from APP.global_xactTable where gxid is not null order by gxid; select * from APP.foo; xa_end xa_success 3; xa_prepare 3; -- should fail with XA_NOTA because we prepared a read only transaction xa_commit xa_1Phase 3; disconnect; </code> */ private static void interleavingTransactions(XADataSource xads) { System.out.println("interleavingTransactions"); try { XAConnection xac = xads.getXAConnection("sku", "testxa"); XAResource xar = xac.getXAResource(); Xid xid1 = XATestUtil.getXid(1, 93, 18); Xid xid2 = XATestUtil.getXid(2, 45, 77); xar.start(xid1, XAResource.TMNOFLAGS); Connection conn = xac.getConnection(); Statement s = conn.createStatement(); s.executeUpdate("insert into APP.foo values (1)"); xar.end(xid1, XAResource.TMSUSPEND); xar.start(xid2, XAResource.TMNOFLAGS); s.executeUpdate("insert into APP.foo values (2)"); xar.end(xid2, XAResource.TMSUSPEND); xar.start(xid1, XAResource.TMRESUME); s.executeUpdate("insert into APP.foo values (3)"); xar.end(xid1, XAResource.TMSUSPEND); xar.start(xid2, XAResource.TMRESUME); s.executeUpdate("insert into APP.foo values (4)"); XATestUtil.showXATransactionView(conn); // this prepare won't work since // transaction 1 has been suspended - XA_PROTO try { xar.prepare(xid1); System.out.println("FAIL - prepare on suspended transaction"); } catch (XAException e) { if (e.errorCode != XAException.XAER_PROTO) XATestUtil.dumpXAException( "FAIL - prepare on suspended transaction", e); } // check it was not prepared XATestUtil.showXATransactionView(conn); xar.end(xid2, XAResource.TMSUCCESS); xar.end(xid1, XAResource.TMSUCCESS); xar.prepare(xid1); xar.prepare(xid2); // both should be prepared. XATestUtil.showXATransactionView(conn); Xid[] recoveredStart = xar.recover(XAResource.TMSTARTRSCAN); System.out.println("recovered start " + recoveredStart.length); Xid[] recovered = xar.recover(XAResource.TMNOFLAGS); System.out.println("recovered " + recovered.length); Xid[] recoveredEnd = xar.recover(XAResource.TMENDRSCAN); System.out.println("recovered end " + recoveredEnd.length); for (int i = 0; i < recoveredStart.length; i++) { Xid xid = recoveredStart[i]; if (xid.getFormatId() == 1) { // commit 1 with 2pc xar.commit(xid, false); } else if (xid.getFormatId() == 2) { xar.rollback(xid); } else { System.out.println("FAIL: unknown xact"); } } // check the results Xid xid3 = XATestUtil.getXid(3, 2, 101); xar.start(xid3, XAResource.TMNOFLAGS); XATestUtil.showXATransactionView(conn); ResultSet rs = s.executeQuery("select * from APP.foo"); JDBCDisplayUtil.DisplayResults(System.out, rs, conn); rs.close(); xar.end(xid3, XAResource.TMSUCCESS); int pr = xar.prepare(xid3); if (pr != XAResource.XA_RDONLY) System.out.println("FAIL - prepare on read only xact returned " + pr); try { xar.commit(xid3, true); System.out.println("FAIL - 2pc commit on read-only xact"); } catch (XAException e) { if (e.errorCode != XAException.XAER_NOTA) throw e; } s.close(); conn.close(); xac.close(); } catch (SQLException sqle) { TestUtil.dumpSQLExceptions(sqle); } catch (XAException e) { XATestUtil.dumpXAException("interleavingTransactions", e); } } /** Tests on INIT STATE (no tr Original SQL from xaStateTran.sql. <code> -- the following should error XAER_NOTA xa_start xa_join 11; -- the following should error XAER_NOTA xa_start xa_resume 11; -- the following should error XAER_NOTA xa_end xa_success 11; -- the following should error XAER_NOTA xa_end xa_fail 11; -- the following should error XAER_NOTA xa_end xa_suspend 11; -- the following should error XAER_NOTA xa_prepare 11; -- the following should error XAER_NOTA xa_commit xa_1phase 11; -- the following should error XAER_NOTA xa_commit xa_2phase 11; -- the following should error XAER_NOTA xa_rollback 11; -- the following should error XAER_NOTA xa_forget 11; </code> */ private static void noTransaction(XADataSource xads) { System.out.println("noTransaction"); try { XAConnection xac = xads.getXAConnection(); XAResource xar = xac.getXAResource(); Xid xid11 = XATestUtil.getXid(11, 3, 128); try { xar.start(xid11, XAResource.TMJOIN); } catch (XAException e) { if (e.errorCode != XAException.XAER_NOTA) throw e; } try { xar.start(xid11, XAResource.TMRESUME); } catch (XAException e) { if (e.errorCode != XAException.XAER_NOTA) throw e; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -