001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.objectserver.gtx;
006:
007: import com.tc.net.groups.ClientID;
008: import com.tc.net.protocol.tcm.ChannelID;
009: import com.tc.object.gtx.GlobalTransactionID;
010: import com.tc.object.tx.ServerTransactionID;
011: import com.tc.object.tx.TransactionID;
012: import com.tc.objectserver.handler.GlobalTransactionIDBatchRequestHandler;
013: import com.tc.objectserver.persistence.api.PersistenceTransaction;
014: import com.tc.objectserver.persistence.impl.TestMutableSequence;
015: import com.tc.objectserver.persistence.impl.TestPersistenceTransactionProvider;
016: import com.tc.objectserver.persistence.impl.TestTransactionStore;
017: import com.tc.util.SequenceValidator;
018: import com.tc.util.sequence.SimpleSequence;
019:
020: import junit.framework.TestCase;
021:
022: public class GlobalTransactionManagerImplTest extends TestCase {
023:
024: private TestTransactionStore transactionStore;
025: private TestPersistenceTransactionProvider ptxp;
026: private ServerGlobalTransactionManager gtxm;
027:
028: protected void setUp() throws Exception {
029: super .setUp();
030: transactionStore = new TestTransactionStore();
031: ptxp = new TestPersistenceTransactionProvider();
032: GlobalTransactionIDSequenceProvider gsp = new GlobalTransactionIDBatchRequestHandler(
033: new TestMutableSequence());
034: gtxm = new ServerGlobalTransactionManagerImpl(
035: new SequenceValidator(0), transactionStore, ptxp, gsp,
036: new SimpleSequence());
037: }
038:
039: public void testStartAndCommitApply() throws Exception {
040: ClientID cid = new ClientID(new ChannelID(1));
041: ServerTransactionID stxID1 = new ServerTransactionID(cid,
042: new TransactionID(1));
043: ServerTransactionID stxID2 = new ServerTransactionID(cid,
044: new TransactionID(2));
045:
046: GlobalTransactionID gtxID1 = gtxm
047: .getOrCreateGlobalTransactionID(stxID1);
048: GlobalTransactionID gtxID2 = gtxm
049: .getOrCreateGlobalTransactionID(stxID2);
050: assertNotSame(gtxID1, gtxID2);
051:
052: assertTrue(gtxm.initiateApply(stxID1));
053: assertTrue(gtxm.initiateApply(stxID2));
054:
055: // the apply has been initiated so
056: assertFalse(gtxm.initiateApply(stxID1));
057: assertFalse(gtxm.initiateApply(stxID2));
058:
059: // now commit them
060: gtxm.commit(null, stxID1);
061: gtxm.commit(null, stxID2);
062:
063: assertFalse(gtxm.initiateApply(stxID1));
064: assertFalse(gtxm.initiateApply(stxID2));
065:
066: // now try to commit again
067: try {
068: gtxm.commit(null, stxID1);
069: fail("TransactionCommittedError");
070: } catch (TransactionCommittedError e) {
071: // expected
072: }
073:
074: transactionStore.restart();
075: }
076:
077: public void testReapplyTransactionsAcrossRestart() throws Exception {
078: ChannelID channel1 = new ChannelID(1);
079: TransactionID tx1 = new TransactionID(1);
080: ServerTransactionID stxid = new ServerTransactionID(
081: new ClientID(channel1), tx1);
082:
083: GlobalTransactionID gid1 = gtxm
084: .getOrCreateGlobalTransactionID(stxid);
085: assertNextGlobalTXWasCalled(stxid);
086:
087: assertTrue(gtxm.initiateApply(stxid));
088: assertGlobalTxWasLoaded(stxid);
089:
090: assertNextGlobalTxNotCalled();
091:
092: // RESTART
093: transactionStore.restart();
094: GlobalTransactionID gid2 = gtxm
095: .getOrCreateGlobalTransactionID(stxid);
096: assertFalse(gid1.equals(gid2));
097: assertNextGlobalTXWasCalled(stxid);
098:
099: // the transaction is still not applied
100: assertTrue(gtxm.initiateApply(stxid));
101: assertGlobalTxWasLoaded(stxid);
102:
103: // no longer needs to be applied
104: assertFalse(gtxm.initiateApply(stxid));
105: assertGlobalTxWasLoaded(stxid);
106:
107: GlobalTransactionID gid3 = gtxm
108: .getOrCreateGlobalTransactionID(stxid);
109: assertTrue(gid2.equals(gid3));
110:
111: gtxm.commit(null, stxid);
112: assertGlobalTxWasLoaded(stxid);
113:
114: assertNotNull(transactionStore.commitContextQueue.poll(1));
115:
116: // make sure no calls to store were made
117: assertTrue(transactionStore.commitContextQueue.isEmpty());
118:
119: // RESTART
120: transactionStore.restart();
121:
122: // make sure that it isn't in progress
123: assertFalse(gtxm.initiateApply(stxid));
124: assertGlobalTxWasLoaded(stxid);
125: assertNextGlobalTxNotCalled();
126:
127: try {
128: gtxm.commit(null, stxid);
129: fail("Should not be able to commit twice");
130: } catch (TransactionCommittedError e) {
131: // expected
132: }
133: assertGlobalTxWasLoaded(stxid);
134: assertNextGlobalTxNotCalled();
135:
136: // APPLY A NEW TRANSACTION
137: ServerTransactionID stxid2 = new ServerTransactionID(
138: new ClientID(channel1), new TransactionID(2));
139: GlobalTransactionID gid4 = gtxm
140: .getOrCreateGlobalTransactionID(stxid2);
141: assertNextGlobalTXWasCalled(stxid2);
142: assertNotSame(gid3, gid4);
143: assertTrue(gtxm.initiateApply(stxid2));
144: assertGlobalTxWasLoaded(stxid2);
145:
146: // apply does create
147: gtxm.getOrCreateGlobalTransactionID(stxid2);
148: gtxm.commit(null, stxid2);
149:
150: assertFalse(gtxm.initiateApply(stxid2));
151:
152: ServerTransactionID stxid3 = new ServerTransactionID(stxid2
153: .getSourceID(), stxid2.getClientTransactionID().next());
154: PersistenceTransaction txn = ptxp.newTransaction();
155: gtxm.clearCommitedTransactionsBelowLowWaterMark(stxid3);
156: txn.commit();
157: }
158:
159: private void assertNextGlobalTXWasCalled(ServerTransactionID stxid) {
160: assertEquals(stxid,
161: transactionStore.nextTransactionIDContextQueue.poll(1));
162: assertNextGlobalTxNotCalled();
163: }
164:
165: private void assertNextGlobalTxNotCalled() {
166: assertTrue(transactionStore.nextTransactionIDContextQueue
167: .isEmpty());
168: }
169:
170: private void assertGlobalTxWasNotLoaded() {
171: assertTrue(transactionStore.loadContextQueue.isEmpty());
172: }
173:
174: private void assertGlobalTxWasLoaded(ServerTransactionID stxid) {
175: ServerTransactionID stxidAsLoadKey = (ServerTransactionID) transactionStore.loadContextQueue
176: .poll(1);
177: assertNotNull(stxidAsLoadKey);
178: assertEquals(stxid, stxidAsLoadKey);
179: assertGlobalTxWasNotLoaded();
180: }
181:
182: }
|