0001: /*
0002:
0003: Derby - Class org.apache.derbyTesting.unitTests.store.T_XA
0004:
0005: Licensed to the Apache Software Foundation (ASF) under one or more
0006: contributor license agreements. See the NOTICE file distributed with
0007: this work for additional information regarding copyright ownership.
0008: The ASF licenses this file to You under the Apache License, Version 2.0
0009: (the "License"); you may not use this file except in compliance with
0010: the License. You may obtain a copy of the License at
0011:
0012: http://www.apache.org/licenses/LICENSE-2.0
0013:
0014: Unless required by applicable law or agreed to in writing, software
0015: distributed under the License is distributed on an "AS IS" BASIS,
0016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: See the License for the specific language governing permissions and
0018: limitations under the License.
0019:
0020: */
0021:
0022: package org.apache.derbyTesting.unitTests.store;
0023:
0024: import org.apache.derbyTesting.unitTests.harness.T_Generic;
0025: import org.apache.derbyTesting.unitTests.harness.T_Fail;
0026:
0027: import org.apache.derby.iapi.store.access.xa.*;
0028: import org.apache.derby.iapi.store.access.*;
0029:
0030: import org.apache.derby.iapi.services.io.FormatableBitSet;
0031:
0032: import org.apache.derby.iapi.reference.Property;
0033:
0034: import org.apache.derby.iapi.services.context.ContextService;
0035: import org.apache.derby.iapi.services.context.ContextManager;
0036:
0037: import org.apache.derby.iapi.services.monitor.Monitor;
0038:
0039: import org.apache.derby.iapi.services.sanity.SanityManager;
0040:
0041: import org.apache.derby.iapi.services.io.FormatIdUtil;
0042:
0043: import org.apache.derby.iapi.error.StandardException;
0044:
0045: import java.util.Properties;
0046:
0047: import javax.transaction.xa.XAResource;
0048: import javax.transaction.xa.Xid;
0049:
0050: public class T_XA extends T_Generic {
0051: private static final String testService = "XaTest";
0052:
0053: byte[] global_id = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
0054: 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
0055: 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 44,
0056: 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
0057: 59, 60, 61, 62, 63 };
0058:
0059: byte[] branch_id = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
0060: 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
0061: 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 44,
0062: 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
0063: 59, 60, 61, 62, 63 };
0064:
0065: AccessFactory store = null;
0066:
0067: public T_XA() {
0068: super ();
0069: }
0070:
0071: /*
0072: ** Methods of UnitTest.
0073: */
0074:
0075: /*
0076: ** Methods required by T_Generic
0077: */
0078:
0079: public String getModuleToTestProtocolName() {
0080: return AccessFactory.MODULE;
0081: }
0082:
0083: /**
0084: @exception T_Fail Unexpected behaviour from the API
0085: */
0086:
0087: protected void runTests() throws T_Fail {
0088: // Create a AccessFactory to test.
0089:
0090: // don't automatic boot this service if it gets left around
0091: if (startParams == null) {
0092: startParams = new Properties();
0093: }
0094: startParams.put(Property.NO_AUTO_BOOT, Boolean.TRUE.toString());
0095: // remove the service directory to ensure a clean run
0096: startParams.put(Property.DELETE_ON_CREATE, Boolean.TRUE
0097: .toString());
0098:
0099: // see if we are testing encryption
0100: startParams = T_Util.setEncryptionParam(startParams);
0101:
0102: try {
0103: store = (AccessFactory) Monitor.createPersistentService(
0104: getModuleToTestProtocolName(), testService,
0105: startParams);
0106: } catch (StandardException mse) {
0107: throw T_Fail.exceptionFail(mse);
0108: }
0109:
0110: if (store == null) {
0111: throw T_Fail.testFailMsg(getModuleToTestProtocolName()
0112: + " service not started.");
0113: }
0114:
0115: REPORT("(unitTestMain) Testing " + testService);
0116:
0117: try {
0118:
0119: XATest_1(new commit_method(store, true));
0120: XATest_2(new commit_method(store, true));
0121: XATest_3(new commit_method(store, true));
0122: XATest_4(new commit_method(store, true));
0123: XATest_5(new commit_method(store, true));
0124: XATest_6(new commit_method(store, true));
0125:
0126: XATest_1(new commit_method(store, false));
0127: XATest_2(new commit_method(store, false));
0128: XATest_3(new commit_method(store, false));
0129: XATest_4(new commit_method(store, false));
0130: XATest_5(new commit_method(store, false));
0131: XATest_6(new commit_method(store, false));
0132: } catch (StandardException e) {
0133: String msg = e.getMessage();
0134: if (msg == null)
0135: msg = e.getClass().getName();
0136: REPORT(msg);
0137: e.printStackTrace();
0138: throw T_Fail.exceptionFail(e);
0139: } catch (Throwable t) {
0140: t.printStackTrace();
0141: }
0142: }
0143:
0144: /**************************************************************************
0145: * Utility methods.
0146: **************************************************************************
0147: */
0148:
0149: /**************************************************************************
0150: * Test Cases.
0151: **************************************************************************
0152: */
0153:
0154: /**
0155: * one phase commit xa transaction.
0156: * <p>
0157: * @exception StandardException Standard exception policy.
0158: **/
0159: void XATest_1(commit_method commit_method)
0160: throws StandardException, T_Fail {
0161: REPORT("(XATest_1) starting");
0162:
0163: ContextManager cm = ContextService.getFactory()
0164: .getCurrentContextManager();
0165:
0166: // COMMIT AN IDLE TRANSACTION.
0167:
0168: // Start a global transaction
0169: XATransactionController xa_tc = (XATransactionController) store
0170: .startXATransaction(cm, 42, // fake format id
0171: global_id, branch_id);
0172:
0173: // commit an idle transaction - using onePhase optimization.
0174: commit_method.commit(true, 42, global_id, branch_id, xa_tc);
0175:
0176: // done with this xact.
0177: xa_tc.destroy();
0178:
0179: // COMMIT AN UPDATE ONLY TRANSACTION.
0180:
0181: // Start a global transaction
0182: xa_tc = (XATransactionController) store.startXATransaction(cm,
0183: 42, // fake format id
0184: global_id, branch_id);
0185:
0186: // Create a heap conglomerate.
0187: T_AccessRow template_row = new T_AccessRow(1);
0188: long conglomid = xa_tc.createConglomerate("heap", // create a heap conglomerate
0189: template_row.getRowArray(), // 1 column template.
0190: null, //column sort order - not required for heap
0191: null, // default properties
0192: TransactionController.IS_DEFAULT); // not temporary
0193:
0194: // commit an idle transaction - using onePhase optimization.
0195: commit_method.commit(true, 42, global_id, branch_id, xa_tc);
0196:
0197: // done with this xact.
0198: xa_tc.destroy();
0199:
0200: // COMMIT A READ ONLY TRANSACTION.
0201:
0202: // Start a global transaction
0203: xa_tc = (XATransactionController) store.startXATransaction(cm,
0204: 42, // fake format id
0205: global_id, branch_id);
0206:
0207: // Open a scan on the conglomerate.
0208: ScanController scan1 = xa_tc.openScan(
0209: conglomid,
0210: false, // don't hold
0211: 0, // not for update
0212: TransactionController.MODE_RECORD,
0213: TransactionController.ISOLATION_SERIALIZABLE,
0214: (FormatableBitSet) null, // all columns, all as objects
0215: null, // start position - first row in conglomerate
0216: 0, // unused if start position is null.
0217: null, // qualifier - accept all rows
0218: null, // stop position - last row in conglomerate
0219: 0); // unused if stop position is null.
0220:
0221: scan1.next();
0222: scan1.close();
0223:
0224: // commit an idle transaction - using onePhase optimization.
0225: commit_method.commit(true, 42, global_id, branch_id, xa_tc);
0226:
0227: // done with this xact.
0228: xa_tc.destroy();
0229:
0230: REPORT("(XATest_1) finishing");
0231: }
0232:
0233: /**
0234: * simple two phase commit xa transaction.
0235: * <p>
0236: * @exception StandardException Standard exception policy.
0237: **/
0238: void XATest_2(commit_method commit_method)
0239: throws StandardException, T_Fail {
0240: REPORT("(XATest_2) starting");
0241: ContextManager cm = ContextService.getFactory()
0242: .getCurrentContextManager();
0243:
0244: // COMMIT AN IDLE TRANSACTION.
0245:
0246: // Start a global transaction
0247: XATransactionController xa_tc = (XATransactionController) store
0248: .startXATransaction(cm, 42, // fake format id
0249: global_id, branch_id);
0250:
0251: if (!xa_tc.isGlobal()) {
0252: throw T_Fail.testFailMsg("should be a global transaction.");
0253: }
0254:
0255: // This prepare will commit the idle transaction.
0256: if (xa_tc.xa_prepare() != XATransactionController.XA_RDONLY) {
0257: throw T_Fail
0258: .testFailMsg("prepare of idle xact did not return XA_RDONLY.");
0259: }
0260:
0261: // commit an idle transaction - using onePhase optimization.
0262: try {
0263: // this should fail as the xact has been committed, so committing
0264: // it in 2 phase mode should fail. This test can't be run in
0265: // offline mode, no transaction will be found. Pass null as
0266: // global_id to make that test not run.
0267:
0268: commit_method.commit(false, 42, null, null, xa_tc);
0269:
0270: throw T_Fail
0271: .testFailMsg("A XA_RDONLY prepare-committed xact cant be 2P xa_committed.");
0272: } catch (StandardException se) {
0273: // expected exception - drop through.
0274: }
0275:
0276: // should not be able to find this global xact, it has been committed
0277: if (((XAResourceManager) store.getXAResourceManager())
0278: .find(new XAXactId(42, global_id, branch_id)) != null) {
0279: throw T_Fail
0280: .testFailMsg("A XA_RDONLY prepare-committed xact should not be findable.");
0281: }
0282:
0283: // done with this xact.
0284: xa_tc.destroy();
0285:
0286: // COMMIT AN UPDATE ONLY TRANSACTION.
0287:
0288: // Start a global transaction
0289: xa_tc = (XATransactionController) store.startXATransaction(cm,
0290: 42, // fake format id
0291: global_id, branch_id);
0292:
0293: // Create a heap conglomerate.
0294: T_AccessRow template_row = new T_AccessRow(1);
0295: long conglomid = xa_tc.createConglomerate("heap", // create a heap conglomerate
0296: template_row.getRowArray(), // 1 column template.
0297: null, //column sort order - not required for heap
0298: null, // default properties
0299: TransactionController.IS_DEFAULT); // not temporary
0300:
0301: // prepare the update xact.
0302: if (xa_tc.xa_prepare() != XATransactionController.XA_OK) {
0303: throw T_Fail
0304: .testFailMsg("prepare of update xact did not return XA_OK.");
0305: }
0306:
0307: // commit an idle transaction - using onePhase optimization.
0308: commit_method.commit(false, 42, global_id, branch_id, xa_tc);
0309:
0310: // done with this xact.
0311: xa_tc.destroy();
0312:
0313: // COMMIT A READ ONLY TRANSACTION.
0314:
0315: // Start a global transaction
0316: xa_tc = (XATransactionController) store.startXATransaction(cm,
0317: 42, // fake format id
0318: global_id, branch_id);
0319:
0320: // Open a scan on the conglomerate.
0321: ScanController scan1 = xa_tc.openScan(
0322: conglomid,
0323: false, // don't hold
0324: 0, // not for update
0325: TransactionController.MODE_RECORD,
0326: TransactionController.ISOLATION_SERIALIZABLE,
0327: (FormatableBitSet) null, // all columns, all as objects
0328: null, // start position - first row in conglomerate
0329: 0, // unused if start position is null.
0330: null, // qualifier - accept all rows
0331: null, // stop position - last row in conglomerate
0332: 0); // unused if stop position is null.
0333:
0334: scan1.next();
0335: scan1.close();
0336:
0337: // This prepare will commit the idle transaction.
0338: if (xa_tc.xa_prepare() != XATransactionController.XA_RDONLY) {
0339: throw T_Fail
0340: .testFailMsg("prepare of idle xact did not return XA_RDONLY.");
0341: }
0342:
0343: // commit an idle transaction - using onePhase optimization.
0344: try {
0345: // this should fail as the xact has been committed, so committing
0346: // it in 2 phase mode should fail. This test can't be run in
0347: // offline mode, no transaction will be found. Pass null as
0348: // global_id to make that test not run.
0349:
0350: commit_method.commit(false, 42, null, null, xa_tc);
0351:
0352: throw T_Fail
0353: .testFailMsg("A XA_RDONLY prepare-committed xact cant be 2P xa_committed.");
0354: } catch (StandardException se) {
0355: // expected exception - drop through.
0356: }
0357:
0358: // should not be able to find this global xact, it has been committed
0359: if (((XAResourceManager) store.getXAResourceManager())
0360: .find(new XAXactId(42, global_id, branch_id)) != null) {
0361: throw T_Fail
0362: .testFailMsg("A XA_RDONLY prepare-committed xact should not be findable.");
0363: }
0364:
0365: // done with this xact.
0366: xa_tc.destroy();
0367:
0368: REPORT("(XATest_2) finishing");
0369: }
0370:
0371: /**
0372: * Test aborts of unprepared xa transaction.
0373: * <p>
0374: * @exception StandardException Standard exception policy.
0375: **/
0376: void XATest_3(commit_method commit_method)
0377: throws StandardException, T_Fail {
0378: REPORT("(XATest_3) starting");
0379:
0380: ContextManager cm = ContextService.getFactory()
0381: .getCurrentContextManager();
0382:
0383: // ABORT AN IDLE TRANSACTION.
0384:
0385: // Start a global transaction
0386: XATransactionController xa_tc = (XATransactionController) store
0387: .startXATransaction(cm, 42, // fake format id
0388: global_id, branch_id);
0389:
0390: // commit an idle transaction - using onePhase optimization.
0391: commit_method.rollback(42, global_id, branch_id, xa_tc);
0392:
0393: // done with this xact.
0394: xa_tc.destroy();
0395:
0396: // ABORT AN UPDATE ONLY TRANSACTION.
0397:
0398: // Start a global transaction
0399: xa_tc = (XATransactionController) store.startXATransaction(cm,
0400: 42, // fake format id
0401: global_id, branch_id);
0402:
0403: // Create a heap conglomerate.
0404: T_AccessRow template_row = new T_AccessRow(1);
0405: long conglomid = xa_tc.createConglomerate("heap", // create a heap conglomerate
0406: template_row.getRowArray(), // 1 column template.
0407: null, //column sort order - not required for heap
0408: null, // default properties
0409: TransactionController.IS_DEFAULT); // not temporary
0410:
0411: // commit an idle transaction - using onePhase optimization.
0412: commit_method.rollback(42, global_id, branch_id, xa_tc);
0413:
0414: // done with this xact.
0415: xa_tc.destroy();
0416:
0417: // ABORT A READ ONLY TRANSACTION.
0418:
0419: // Start a global transaction
0420: xa_tc = (XATransactionController) store.startXATransaction(cm,
0421: 42, // fake format id
0422: global_id, branch_id);
0423:
0424: // Create a heap conglomerate.
0425: template_row = new T_AccessRow(1);
0426: conglomid = xa_tc.createConglomerate("heap", // create a heap conglomerate
0427: template_row.getRowArray(), // 1 column template.
0428: null, //column sort order - not required for heap
0429: null, // default properties
0430: TransactionController.IS_DEFAULT); // not temporary
0431:
0432: // commit an idle transaction - using onePhase optimization.
0433: commit_method.commit(true, 42, global_id, branch_id, xa_tc);
0434:
0435: // done with this xact.
0436: xa_tc.destroy();
0437:
0438: // Start a global transaction
0439: xa_tc = (XATransactionController) store.startXATransaction(cm,
0440: 42, // fake format id
0441: global_id, branch_id);
0442:
0443: // Open a scan on the conglomerate.
0444: ScanController scan1 = xa_tc.openScan(
0445: conglomid,
0446: false, // don't hold
0447: 0, // not for update
0448: TransactionController.MODE_RECORD,
0449: TransactionController.ISOLATION_SERIALIZABLE,
0450: (FormatableBitSet) null, // all columns, all as objects
0451: null, // start position - first row in conglomerate
0452: 0, // unused if start position is null.
0453: null, // qualifier - accept all rows
0454: null, // stop position - last row in conglomerate
0455: 0); // unused if stop position is null.
0456:
0457: scan1.next();
0458: scan1.close();
0459:
0460: // commit an idle transaction - using onePhase optimization.
0461: commit_method.rollback(42, global_id, branch_id, xa_tc);
0462:
0463: // done with this xact.
0464: xa_tc.destroy();
0465:
0466: REPORT("(XATest_3) finishing");
0467: }
0468:
0469: /**
0470: * Test aborts of prepared two phase commit xa transaction.
0471: * <p>
0472: * @exception StandardException Standard exception policy.
0473: **/
0474: void XATest_4(commit_method commit_method)
0475: throws StandardException, T_Fail {
0476: REPORT("(XATest_4) starting");
0477:
0478: ContextManager cm = ContextService.getFactory()
0479: .getCurrentContextManager();
0480:
0481: // ABORT AN IDLE TRANSACTION.
0482:
0483: // Start a global transaction
0484: XATransactionController xa_tc = (XATransactionController) store
0485: .startXATransaction(cm, 42, // fake format id
0486: global_id, branch_id);
0487:
0488: // This prepare will commit the idle transaction.
0489: if (xa_tc.xa_prepare() != XATransactionController.XA_RDONLY) {
0490: throw T_Fail
0491: .testFailMsg("prepare of idle xact did not return XA_RDONLY.");
0492: }
0493:
0494: // nothing to do, will just abort the next current idle xact.
0495:
0496: // after prepare/readonly we cna continue to use transaction
0497: commit_method.commit(true, 42, null, null, xa_tc);
0498:
0499: // should not be able to find this global xact, it has been committed
0500: if (((XAResourceManager) store.getXAResourceManager())
0501: .find(new XAXactId(42, global_id, branch_id)) != null) {
0502: throw T_Fail
0503: .testFailMsg("A XA_RDONLY prepare-committed xact should not be findable.");
0504: }
0505:
0506: // done with this xact.
0507: xa_tc.destroy();
0508:
0509: // ABORT AN UPDATE ONLY TRANSACTION.
0510:
0511: // Start a global transaction
0512: xa_tc = (XATransactionController) store.startXATransaction(cm,
0513: 42, // fake format id
0514: global_id, branch_id);
0515:
0516: // Create a heap conglomerate.
0517: T_AccessRow template_row = new T_AccessRow(1);
0518: long conglomid = xa_tc.createConglomerate("heap", // create a heap conglomerate
0519: template_row.getRowArray(), // 1 column template.
0520: null, //column sort order - not required for heap
0521: null, // default properties
0522: TransactionController.IS_DEFAULT); // not temporary
0523:
0524: // Open a scan on the conglomerate, to verify the create happened,
0525: // and to show that the same openScan done after abort fails.
0526: ScanController scan1 = xa_tc.openScan(
0527: conglomid,
0528: false, // don't hold
0529: 0, // not for update
0530: TransactionController.MODE_RECORD,
0531: TransactionController.ISOLATION_SERIALIZABLE,
0532: (FormatableBitSet) null, // all columns, all as objects
0533: null, // start position - first row in conglomerate
0534: 0, // unused if start position is null.
0535: null, // qualifier - accept all rows
0536: null, // stop position - last row in conglomerate
0537: 0); // unused if stop position is null.
0538:
0539: scan1.next();
0540: scan1.close();
0541:
0542: // prepare the update xact.
0543: if (xa_tc.xa_prepare() != XATransactionController.XA_OK) {
0544: throw T_Fail
0545: .testFailMsg("prepare of update xact did not return XA_OK.");
0546: }
0547:
0548: try {
0549: // Open a scan on the conglomerate.
0550: scan1 = xa_tc.openScan(
0551: conglomid,
0552: false, // don't hold
0553: 0, // not for update
0554: TransactionController.MODE_RECORD,
0555: TransactionController.ISOLATION_SERIALIZABLE,
0556: (FormatableBitSet) null, // all columns, all as objects
0557: null, // start position - first row in conglomerate
0558: 0, // unused if start position is null.
0559: null, // qualifier - accept all rows
0560: null, // stop position - last row in conglomerate
0561: 0); // unused if stop position is null.
0562:
0563: scan1.next();
0564: scan1.close();
0565:
0566: throw T_Fail
0567: .testFailMsg("Should not be able to do anything on xact after prepare.");
0568: } catch (StandardException se) {
0569: // expected exception, fall through.
0570: }
0571:
0572: // commit an idle transaction - using onePhase optimization.
0573: commit_method.rollback(42, global_id, branch_id, xa_tc);
0574:
0575: commit_method.commit(true, 42, null, null, xa_tc);
0576:
0577: // should not be able to find this global xact, it has been committed
0578: if (((XAResourceManager) store.getXAResourceManager())
0579: .find(new XAXactId(42, global_id, branch_id)) != null) {
0580: throw T_Fail
0581: .testFailMsg("A xa_rollbacked xact should not be findable.");
0582: }
0583:
0584: // done with this xact.
0585: xa_tc.destroy();
0586:
0587: // Start a global transaction
0588: xa_tc = (XATransactionController) store.startXATransaction(cm,
0589: 42, // fake format id
0590: global_id, branch_id);
0591:
0592: try {
0593: // Open a scan on the conglomerate.
0594: scan1 = xa_tc.openScan(
0595: conglomid,
0596: false, // don't hold
0597: 0, // not for update
0598: TransactionController.MODE_RECORD,
0599: TransactionController.ISOLATION_SERIALIZABLE,
0600: (FormatableBitSet) null, // all columns, all as objects
0601: null, // start position - first row in conglomerate
0602: 0, // unused if start position is null.
0603: null, // qualifier - accept all rows
0604: null, // stop position - last row in conglomerate
0605: 0); // unused if stop position is null.
0606:
0607: scan1.next();
0608: scan1.close();
0609:
0610: throw T_Fail
0611: .testFailMsg("Should not be able to open conglom, the create was aborted.");
0612: } catch (StandardException se) {
0613: // expected exception, fall through.
0614: }
0615:
0616: xa_tc.destroy();
0617:
0618: // ABORT A READ ONLY TRANSACTION.
0619:
0620: // Start a global transaction
0621: xa_tc = (XATransactionController) store.startXATransaction(cm,
0622: 42, // fake format id
0623: global_id, branch_id);
0624:
0625: // Create a heap conglomerate.
0626: template_row = new T_AccessRow(1);
0627: conglomid = xa_tc.createConglomerate("heap", // create a heap conglomerate
0628: template_row.getRowArray(), // 1 column template.
0629: null, //column sort order - not required for heap
0630: null, // default properties
0631: TransactionController.IS_DEFAULT); // not temporary
0632:
0633: commit_method.commit(true, 42, global_id, branch_id, xa_tc);
0634:
0635: xa_tc.destroy();
0636:
0637: // Start a global transaction
0638: xa_tc = (XATransactionController) store.startXATransaction(cm,
0639: 42, // fake format id
0640: global_id, branch_id);
0641:
0642: // Open a scan on the conglomerate.
0643: scan1 = xa_tc.openScan(
0644: conglomid,
0645: false, // don't hold
0646: 0, // not for update
0647: TransactionController.MODE_RECORD,
0648: TransactionController.ISOLATION_SERIALIZABLE,
0649: (FormatableBitSet) null, // all columns, all as objects
0650: null, // start position - first row in conglomerate
0651: 0, // unused if start position is null.
0652: null, // qualifier - accept all rows
0653: null, // stop position - last row in conglomerate
0654: 0); // unused if stop position is null.
0655:
0656: scan1.next();
0657: scan1.close();
0658:
0659: // This prepare will commit the idle transaction.
0660: if (xa_tc.xa_prepare() != XATransactionController.XA_RDONLY) {
0661: throw T_Fail
0662: .testFailMsg("prepare of idle xact did not return XA_RDONLY.");
0663: }
0664:
0665: // commit an idle transaction - using onePhase optimization.
0666: commit_method.commit(true, 42, null, null, xa_tc);
0667:
0668: // should not be able to find this global xact, it has been committed
0669: if (((XAResourceManager) store.getXAResourceManager())
0670: .find(new XAXactId(42, global_id, branch_id)) != null) {
0671: throw T_Fail
0672: .testFailMsg("A XA_RDONLY prepare-committed xact should not be findable.");
0673: }
0674:
0675: // done with this xact.
0676: xa_tc.destroy();
0677:
0678: REPORT("(XATest_5) finishing");
0679: }
0680:
0681: /**
0682: * Very simple testing of the recover() call.
0683: * <p>
0684: * @exception StandardException Standard exception policy.
0685: **/
0686: void XATest_5(commit_method commit_method)
0687: throws StandardException, T_Fail {
0688: REPORT("(XATest_5) starting");
0689:
0690: // Should be no prepared transactions when we first start.
0691: if (((XAResourceManager) store.getXAResourceManager())
0692: .recover(XAResource.TMSTARTRSCAN).length != 0) {
0693: throw T_Fail
0694: .testFailMsg("recover incorrectly returned prepared xacts.");
0695: }
0696:
0697: // Should be no prepared transactions when we first start.
0698: if (((XAResourceManager) store.getXAResourceManager())
0699: .recover(XAResource.TMNOFLAGS).length != 0) {
0700: throw T_Fail.testFailMsg("NOFLAGS should always return 0.");
0701: }
0702:
0703: ContextManager cm = ContextService.getFactory()
0704: .getCurrentContextManager();
0705:
0706: // COMMIT AN IDLE TRANSACTION.
0707:
0708: // Start a global transaction
0709: XATransactionController xa_tc = (XATransactionController) store
0710: .startXATransaction(cm, 42, // fake format id
0711: global_id, branch_id);
0712:
0713: // Should be no prepared transactions, there is one idle global xact.
0714: if (((XAResourceManager) store.getXAResourceManager())
0715: .recover(XAResource.TMSTARTRSCAN).length != 0) {
0716: throw T_Fail
0717: .testFailMsg("recover incorrectly returned prepared xacts.");
0718: }
0719:
0720: // commit an idle transaction - using onePhase optimization.
0721: commit_method.commit(true, 42, global_id, branch_id, xa_tc);
0722:
0723: // done with this xact.
0724: xa_tc.destroy();
0725:
0726: // COMMIT AN UPDATE ONLY TRANSACTION.
0727:
0728: // Start a global transaction
0729: xa_tc = (XATransactionController) store.startXATransaction(cm,
0730: 42, // fake format id
0731: global_id, branch_id);
0732:
0733: // Create a heap conglomerate.
0734: T_AccessRow template_row = new T_AccessRow(1);
0735: long conglomid = xa_tc.createConglomerate("heap", // create a heap conglomerate
0736: template_row.getRowArray(), // 1 column template.
0737: null, //column sort order - not required for heap
0738: null, // default properties
0739: TransactionController.IS_DEFAULT); // not temporary
0740:
0741: // Should be no prepared transactions, there is one update global xact.
0742: if (((XAResourceManager) store.getXAResourceManager())
0743: .recover(XAResource.TMSTARTRSCAN).length != 0) {
0744: throw T_Fail
0745: .testFailMsg("recover incorrectly returned prepared xacts.");
0746: }
0747:
0748: // commit an idle transaction - using onePhase optimization.
0749: commit_method.commit(true, 42, global_id, branch_id, xa_tc);
0750:
0751: // done with this xact.
0752: xa_tc.destroy();
0753:
0754: // COMMIT A READ ONLY TRANSACTION.
0755:
0756: // Start a global transaction
0757: xa_tc = (XATransactionController) store.startXATransaction(cm,
0758: 42, // fake format id
0759: global_id, branch_id);
0760:
0761: // Open a scan on the conglomerate.
0762: ScanController scan1 = xa_tc.openScan(
0763: conglomid,
0764: false, // don't hold
0765: 0, // not for update
0766: TransactionController.MODE_RECORD,
0767: TransactionController.ISOLATION_SERIALIZABLE,
0768: (FormatableBitSet) null, // all columns, all as objects
0769: null, // start position - first row in conglomerate
0770: 0, // unused if start position is null.
0771: null, // qualifier - accept all rows
0772: null, // stop position - last row in conglomerate
0773: 0); // unused if stop position is null.
0774:
0775: scan1.next();
0776: scan1.close();
0777:
0778: // Should be no prepared transactions, there is one update global xact.
0779: if (((XAResourceManager) store.getXAResourceManager())
0780: .recover(XAResource.TMSTARTRSCAN).length != 0) {
0781: throw T_Fail
0782: .testFailMsg("recover incorrectly returned prepared xacts.");
0783: }
0784:
0785: // commit an idle transaction - using onePhase optimization.
0786: commit_method.commit(true, 42, global_id, branch_id, xa_tc);
0787:
0788: // done with this xact.
0789: xa_tc.destroy();
0790:
0791: // PREPARE AN UPDATE TRANSACTION.
0792:
0793: // Start a global transaction
0794: xa_tc = (XATransactionController) store.startXATransaction(cm,
0795: 42, // fake format id
0796: global_id, branch_id);
0797:
0798: // Create a heap conglomerate.
0799: template_row = new T_AccessRow(1);
0800: conglomid = xa_tc.createConglomerate("heap", // create a heap conglomerate
0801: template_row.getRowArray(), // 1 column template.
0802: null, //column sort order - not required for heap
0803: null, // default properties
0804: TransactionController.IS_DEFAULT); // not temporary
0805:
0806: // Should be no prepared transactions, there is one update global xact.
0807: if (((XAResourceManager) store.getXAResourceManager())
0808: .recover(XAResource.TMSTARTRSCAN).length != 0) {
0809: throw T_Fail
0810: .testFailMsg("recover incorrectly returned prepared xacts.");
0811: }
0812:
0813: // prepare the update xact.
0814: if (xa_tc.xa_prepare() != XATransactionController.XA_OK) {
0815: throw T_Fail
0816: .testFailMsg("prepare of update xact did not return XA_OK.");
0817: }
0818:
0819: try {
0820: // Open a scan on the conglomerate.
0821: scan1 = xa_tc.openScan(
0822: conglomid,
0823: false, // don't hold
0824: 0, // not for update
0825: TransactionController.MODE_RECORD,
0826: TransactionController.ISOLATION_SERIALIZABLE,
0827: (FormatableBitSet) null, // all columns, all as objects
0828: null, // start position - first row in conglomerate
0829: 0, // unused if start position is null.
0830: null, // qualifier - accept all rows
0831: null, // stop position - last row in conglomerate
0832: 0); // unused if stop position is null.
0833:
0834: scan1.next();
0835: scan1.close();
0836:
0837: throw T_Fail
0838: .testFailMsg("Should not be able to do anything on xact after prepare.");
0839: } catch (StandardException se) {
0840: // expected exception, fall through.
0841: }
0842:
0843: // Should be no prepared transactions, there is one update global xact.
0844: Xid[] prepared_xacts = ((XAResourceManager) store
0845: .getXAResourceManager())
0846: .recover(XAResource.TMSTARTRSCAN);
0847:
0848: if (prepared_xacts.length != 1) {
0849: throw T_Fail
0850: .testFailMsg("recover incorrectly returned wrong prepared xacts.");
0851: }
0852:
0853: if (prepared_xacts[0].getFormatId() != 42)
0854: throw T_Fail.testFailMsg("bad format id = "
0855: + prepared_xacts[0].getFormatId());
0856:
0857: byte[] gid = prepared_xacts[0].getGlobalTransactionId();
0858:
0859: if (!java.util.Arrays.equals(gid, global_id)) {
0860: throw T_Fail.testFailMsg("bad global id = "
0861: + org.apache.derbyTesting.unitTests.util.BitUtil
0862: .hexDump(gid));
0863: }
0864:
0865: byte[] bid = prepared_xacts[0].getBranchQualifier();
0866:
0867: if (!java.util.Arrays.equals(bid, branch_id)) {
0868: throw T_Fail.testFailMsg("bad branch id = "
0869: + org.apache.derbyTesting.unitTests.util.BitUtil
0870: .hexDump(bid));
0871: }
0872:
0873: if (((XAResourceManager) store.getXAResourceManager())
0874: .recover(XAResource.TMNOFLAGS).length != 0) {
0875: throw T_Fail.testFailMsg("NOFLAGS should always return 0.");
0876: }
0877:
0878: // commit a prepared transaction - using two phase.
0879: commit_method.commit(false, 42, global_id, branch_id, xa_tc);
0880:
0881: // Should be no prepared transactions, there is one update global xact.
0882: if (((XAResourceManager) store.getXAResourceManager())
0883: .recover(XAResource.TMSTARTRSCAN).length != 0) {
0884: throw T_Fail
0885: .testFailMsg("recover incorrectly returned prepared xacts.");
0886: }
0887:
0888: // done with this xact.
0889: xa_tc.destroy();
0890:
0891: // Should be no prepared transactions, there is one update global xact.
0892: if (((XAResourceManager) store.getXAResourceManager())
0893: .recover(XAResource.TMSTARTRSCAN).length != 0) {
0894: throw T_Fail
0895: .testFailMsg("recover incorrectly returned prepared xacts.");
0896: }
0897:
0898: REPORT("(XATest_5) finishing");
0899:
0900: }
0901:
0902: /**
0903: * Very simple testing of changing a local transaction to a global.
0904: * <p>
0905: * @exception StandardException Standard exception policy.
0906: **/
0907: void XATest_6(commit_method commit_method)
0908: throws StandardException, T_Fail {
0909: REPORT("(XATest_5) starting");
0910:
0911: ContextManager cm = ContextService.getFactory()
0912: .getCurrentContextManager();
0913:
0914: TransactionController tc = store.getTransaction(cm);
0915:
0916: // Create a heap conglomerate.
0917: T_AccessRow template_row = new T_AccessRow(1);
0918: long conglomid = tc.createConglomerate("heap", // create a heap conglomerate
0919: template_row.getRowArray(), // 1 column template.
0920: null, //column sort order - not required for heap
0921: null, // default properties
0922: TransactionController.IS_DEFAULT); // not temporary
0923:
0924: tc.commit();
0925:
0926: // COMMIT AN IDLE TRANSACTION.
0927:
0928: // Start a global transaction
0929: XATransactionController xa_tc = (XATransactionController) tc
0930: .createXATransactionFromLocalTransaction(42, // fake format id
0931: global_id, branch_id);
0932:
0933: if (!xa_tc.isGlobal()) {
0934: throw T_Fail.testFailMsg("should be a global transaction.");
0935: }
0936:
0937: // Open a scan on the conglomerate.
0938: ScanController scan1 = xa_tc.openScan(
0939: conglomid,
0940: false, // don't hold
0941: 0, // not for update
0942: TransactionController.MODE_RECORD,
0943: TransactionController.ISOLATION_SERIALIZABLE,
0944: (FormatableBitSet) null, // all columns, all as objects
0945: null, // start position - first row in conglomerate
0946: 0, // unused if start position is null.
0947: null, // qualifier - accept all rows
0948: null, // stop position - last row in conglomerate
0949: 0); // unused if stop position is null.
0950:
0951: scan1.next();
0952: scan1.close();
0953:
0954: // Create a heap conglomerate.
0955: template_row = new T_AccessRow(1);
0956: conglomid = xa_tc.createConglomerate("heap", // create a heap conglomerate
0957: template_row.getRowArray(), // 1 column template.
0958: null, //column sort order - not required for heap
0959: null, // default properties
0960: TransactionController.IS_DEFAULT); // not temporary
0961:
0962: // Should be no prepared transactions, there is one update global xact.
0963: if (((XAResourceManager) store.getXAResourceManager())
0964: .recover(XAResource.TMSTARTRSCAN).length != 0) {
0965: throw T_Fail
0966: .testFailMsg("recover incorrectly returned prepared xacts.");
0967: }
0968:
0969: // prepare the update xact.
0970: if (xa_tc.xa_prepare() != XATransactionController.XA_OK) {
0971: throw T_Fail
0972: .testFailMsg("prepare of update xact did not return XA_OK.");
0973: }
0974:
0975: try {
0976: // Open a scan on the conglomerate.
0977: scan1 = xa_tc.openScan(
0978: conglomid,
0979: false, // don't hold
0980: 0, // not for update
0981: TransactionController.MODE_RECORD,
0982: TransactionController.ISOLATION_SERIALIZABLE,
0983: (FormatableBitSet) null, // all columns, all as objects
0984: null, // start position - first row in conglomerate
0985: 0, // unused if start position is null.
0986: null, // qualifier - accept all rows
0987: null, // stop position - last row in conglomerate
0988: 0); // unused if stop position is null.
0989:
0990: scan1.next();
0991: scan1.close();
0992:
0993: throw T_Fail
0994: .testFailMsg("Should not be able to do anything on xact after prepare.");
0995: } catch (StandardException se) {
0996: // expected exception, fall through.
0997: }
0998:
0999: // commit a prepared transaction - using two phase.
1000: commit_method.commit(false, 42, global_id, branch_id, xa_tc);
1001:
1002: xa_tc.destroy();
1003:
1004: REPORT("(XATest_6) finishing");
1005: }
1006:
1007: }
1008:
1009: class commit_method {
1010: private boolean online_xact;
1011: private AccessFactory store;
1012:
1013: public commit_method(AccessFactory store, boolean online_xact) {
1014: this .store = store;
1015: this .online_xact = online_xact;
1016: }
1017:
1018: public void commit(boolean one_phase, int format_id,
1019: byte[] global_id, byte[] branch_id,
1020: XATransactionController xa_tc) throws StandardException {
1021: if (SanityManager.DEBUG)
1022: SanityManager
1023: .ASSERT((global_id != null) || (xa_tc != null));
1024:
1025: boolean local_online_xact = online_xact;
1026:
1027: if (global_id == null)
1028: local_online_xact = true;
1029: if (xa_tc == null)
1030: local_online_xact = false;
1031:
1032: if (local_online_xact) {
1033: xa_tc.xa_commit(one_phase);
1034: } else {
1035: Xid xid = new XAXactId(format_id, global_id, branch_id);
1036:
1037: ContextManager cm = ((XAResourceManager) store
1038: .getXAResourceManager()).find(xid);
1039:
1040: if (SanityManager.DEBUG) {
1041: SanityManager.ASSERT(cm != null,
1042: "could not find xid = " + xid);
1043:
1044: SanityManager.ASSERT(cm == ContextService.getFactory()
1045: .getCurrentContextManager(), "cm = "
1046: + cm
1047: + "current = "
1048: + ContextService.getFactory()
1049: .getCurrentContextManager());
1050: }
1051:
1052: ((XAResourceManager) store.getXAResourceManager()).commit(
1053: cm, xid, one_phase);
1054: }
1055: }
1056:
1057: public void rollback(int format_id, byte[] global_id,
1058: byte[] branch_id, XATransactionController xa_tc)
1059: throws StandardException {
1060: if (SanityManager.DEBUG)
1061: SanityManager
1062: .ASSERT((global_id != null) || (xa_tc != null));
1063:
1064: boolean local_online_xact = online_xact;
1065:
1066: if (global_id == null)
1067: local_online_xact = true;
1068: if (xa_tc == null)
1069: local_online_xact = false;
1070:
1071: if (local_online_xact) {
1072: xa_tc.xa_rollback();
1073: } else {
1074: Xid xid = new XAXactId(format_id, global_id, branch_id);
1075:
1076: ContextManager cm = ((XAResourceManager) store
1077: .getXAResourceManager()).find(xid);
1078:
1079: if (SanityManager.DEBUG) {
1080: SanityManager.ASSERT(cm != null,
1081: "could not find xid = " + xid);
1082:
1083: SanityManager.ASSERT(cm == ContextService.getFactory()
1084: .getCurrentContextManager(), "cm = "
1085: + cm
1086: + "current = "
1087: + ContextService.getFactory()
1088: .getCurrentContextManager());
1089: }
1090:
1091: ((XAResourceManager) store.getXAResourceManager())
1092: .rollback(cm, xid);
1093: }
1094: }
1095: }
|