001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.objectserver.persistence.sleepycat;
006:
007: import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
008:
009: import com.sleepycat.je.DatabaseConfig;
010: import com.sleepycat.je.EnvironmentConfig;
011: import com.tc.net.groups.ClientID;
012: import com.tc.net.protocol.tcm.ChannelID;
013: import com.tc.object.gtx.GlobalTransactionID;
014: import com.tc.object.tx.ServerTransactionID;
015: import com.tc.object.tx.TransactionID;
016: import com.tc.objectserver.gtx.GlobalTransactionDescriptor;
017: import com.tc.objectserver.persistence.api.PersistenceTransaction;
018: import com.tc.test.TCTestCase;
019:
020: import java.io.File;
021: import java.io.IOException;
022: import java.util.ArrayList;
023: import java.util.Collection;
024: import java.util.HashMap;
025: import java.util.List;
026: import java.util.Map;
027:
028: public class TransactionPersistorTest extends TCTestCase {
029:
030: private File envHome;
031: private EnvironmentConfig ecfg;
032: private DatabaseConfig dbcfg;
033: private static int count = 0;
034:
035: protected void setUp() throws Exception {
036: super .setUp();
037: ecfg = new EnvironmentConfig();
038: ecfg.setAllowCreate(true);
039: ecfg.setReadOnly(false);
040: ecfg.setTransactional(true);
041:
042: dbcfg = new DatabaseConfig();
043: dbcfg.setAllowCreate(true);
044: dbcfg.setReadOnly(false);
045: dbcfg.setTransactional(true);
046: while ((envHome = new File(this .getTempDirectory(), ++count
047: + "")).exists()) {
048: //
049: }
050: System.out.println("DB home: " + envHome);
051: }
052:
053: private DBEnvironment newEnv(boolean paranoid) throws IOException {
054: return newEnv(new HashMap(), new ArrayList(), paranoid);
055: }
056:
057: private DBEnvironment newEnv(Map map, List list, boolean paranoid)
058: throws IOException {
059: return new DBEnvironment(map, list, paranoid, envHome, ecfg,
060: dbcfg);
061: }
062:
063: /**
064: * This test was written just so that I can understand sleepycat behavior under various conditions. Things that I noticed are
065: * 1) If save happens before delete, delete doesnt go thru until save is committed. (record level lock)
066: * 2) If commit doesnt happen with the default(500ms) time sleepcat throws a deadlock exception.
067: */
068: public void testSimultaneousSaveAndDeletes() throws Exception {
069: DBEnvironment env = newEnv(true);
070: assertTrue(env.open().isClean());
071: final SleepycatPersistenceTransactionProvider persistenceTransactionProvider = new SleepycatPersistenceTransactionProvider(
072: env.getEnvironment());
073: final TransactionPersistorImpl tpl = new TransactionPersistorImpl(
074: env.getTransactionDatabase(),
075: persistenceTransactionProvider);
076: final ServerTransactionID sid = new ServerTransactionID(
077: new ClientID(new ChannelID(9)), new TransactionID(10));
078: final GlobalTransactionDescriptor gtd = new GlobalTransactionDescriptor(
079: sid, new GlobalTransactionID(909));
080: final CyclicBarrier cb = new CyclicBarrier(2);
081: final Exception ex[] = new Exception[2];
082:
083: Thread t1 = new Thread() {
084: public void run() {
085: try {
086: Collection gdts = tpl
087: .loadAllGlobalTransactionDescriptors();
088: assertEquals(0, gdts.size());
089: PersistenceTransaction pt = persistenceTransactionProvider
090: .newTransaction();
091: tpl.saveGlobalTransactionDescriptor(pt, gtd);
092: System.err.println("T1 : save done.");
093: cb.barrier();
094: pt.commit();
095: System.err.println("T1 : save commit done.");
096: gdts = tpl.loadAllGlobalTransactionDescriptors();
097: assertEquals(0, gdts.size());
098: } catch (Exception e) {
099: e.printStackTrace();
100: ex[0] = e;
101: }
102: }
103: };
104:
105: Thread t2 = new Thread() {
106: public void run() {
107: try {
108: PersistenceTransaction pt = persistenceTransactionProvider
109: .newTransaction();
110: ArrayList al = new ArrayList();
111: al.add(gtd);
112: cb.barrier();
113: tpl.deleteAllGlobalTransactionDescriptors(pt, al);
114: System.err.println("T2 : Delete done");
115: pt.commit();
116: System.err.println("T2 : Delete commit done");
117: } catch (Exception e) {
118: e.printStackTrace();
119: ex[1] = e;
120: }
121: }
122: };
123:
124: t1.start();
125: t2.start();
126:
127: t1.join();
128: t2.join();
129: if (ex[0] != null)
130: throw ex[0];
131: if (ex[1] != null)
132: throw ex[1];
133: }
134:
135: protected void tearDown() throws Exception {
136: super.tearDown();
137: }
138:
139: }
|