001: /**
002: * Speedo: an implementation of JDO compliant personality on top of JORM generic
003: * I/O sub-system.
004: * Copyright (C) 2001-2004 France Telecom R&D
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: *
021: *
022: * Contact: speedo@objectweb.org
023: *
024: * Authors: S.Chassande-Barrioz.
025: *
026: */package org.objectweb.speedo.runtime.concurrency;
027:
028: import org.objectweb.speedo.SpeedoTestHelper;
029: import org.objectweb.speedo.api.ExceptionHelper;
030: import org.objectweb.speedo.pobjects.basic.BasicA;
031: import org.objectweb.util.monolog.api.BasicLevel;
032:
033: import javax.jdo.PersistenceManager;
034: import javax.jdo.JDOException;
035: import javax.jdo.JDOFatalException;
036:
037: import junit.framework.Assert;
038:
039: import java.util.Properties;
040:
041: public class TestPessimistic extends SpeedoTestHelper {
042:
043: public TestPessimistic(String s) {
044: super (s);
045: }
046:
047: protected String getLoggerName() {
048: return LOG_NAME + ".rt.concurrency.TestPessimistic";
049: }
050:
051: public Properties getPMFProperties() {
052: Properties p = super .getPMFProperties();
053: p.setProperty("javax.jdo.option.Optimistic", "false");
054: return p;
055: }
056:
057: public void testConcurrentReads() {
058: logger.log(BasicLevel.INFO, "test concurrent reads");
059: // setup
060: BasicA ba = new BasicA();
061: ba.writeF1("1");
062: ba.writeF2(2);
063: PersistenceManager pm = pmf.getPersistenceManager();
064: pm.currentTransaction().begin();
065: pm.makePersistent(ba);
066: final Object id = pm.getObjectId(ba);
067: Assert.assertNotNull("Null object identifier", id);
068: pm.currentTransaction().commit();
069: pm.close();
070:
071: ba = null;
072:
073: // begin transaction 1
074: PersistenceManager pm1 = pmf.getPersistenceManager();
075: logger.log(BasicLevel.INFO, "Thread1: begin");
076: pm1.currentTransaction().begin();
077: logger.log(BasicLevel.INFO, "Thread1: getObjectById");
078: ba = (BasicA) pm1.getObjectById(id, true);
079: Assert.assertNotNull("Object not found", ba);
080: logger.log(BasicLevel.INFO, "Thread1: read");
081: ba.readF2();
082: logger.log(BasicLevel.INFO, "Thread1: read done");
083:
084: // begin transaction 2
085: Thread t = new Thread((new Runnable() {
086: public void run() {
087: PersistenceManager pm2 = pmf.getPersistenceManager();
088: logger.log(BasicLevel.INFO, "Thread2: begin");
089: pm2.currentTransaction().begin();
090: logger.log(BasicLevel.INFO, "Thread2: getObjectById");
091: BasicA ba = (BasicA) pm2.getObjectById(id, true);
092: Assert.assertNotNull("Object not found", ba);
093: logger.log(BasicLevel.INFO, "Thread2: read");
094: ba.readF2();
095: logger.log(BasicLevel.INFO, "Thread2: read done");
096: logger.log(BasicLevel.INFO, "Thread2: commit");
097: pm2.currentTransaction().commit();
098: pm2.close();
099: }
100: }));
101: t.start();
102:
103: // end transaction 1
104: logger.log(BasicLevel.INFO, "Thread1: commit");
105: pm1.currentTransaction().commit();
106: pm1.close();
107:
108: assertUnlock(t);
109:
110: // clean up
111: pm = pmf.getPersistenceManager();
112: pm.currentTransaction().begin();
113: ba = (BasicA) pm.getObjectById(id, true);
114: Assert.assertNotNull("Object not found", ba);
115: Assert.assertEquals("Bad f1 value", "1", ba.readF1());
116: Assert.assertEquals("Bad f2 value", 2, ba.readF2());
117: pm.deletePersistent(ba);
118: pm.currentTransaction().commit();
119: pm.close();
120: }
121:
122: public void testReadConcurrentWrite() {
123: logger.log(BasicLevel.INFO, "test read concurrent write");
124: // setup
125: BasicA ba = new BasicA();
126: ba.writeF1("1");
127: ba.writeF2(2);
128: PersistenceManager pm = pmf.getPersistenceManager();
129: pm.currentTransaction().begin();
130: pm.makePersistent(ba);
131: final Object id = pm.getObjectId(ba);
132: Assert.assertNotNull("Null object identifier", id);
133: pm.currentTransaction().commit();
134: pm.close();
135:
136: ba = null;
137:
138: // begin transaction 1
139: PersistenceManager pm1 = pmf.getPersistenceManager();
140: logger.log(BasicLevel.INFO, "Thread1: begin");
141: pm1.currentTransaction().begin();
142: logger.log(BasicLevel.INFO, "Thread1: getObjectById");
143: ba = (BasicA) pm1.getObjectById(id, true);
144: Assert.assertNotNull("Object not found", ba);
145: logger.log(BasicLevel.INFO, "Thread1: read");
146: ba.readF2();
147: logger.log(BasicLevel.INFO, "Thread1: read done");
148:
149: // begin transaction 2
150: Thread t = assertLock(new Runnable() {
151: public void run() {
152: PersistenceManager pm2 = pmf.getPersistenceManager();
153: logger.log(BasicLevel.INFO, "Thread2: begin");
154: pm2.currentTransaction().begin();
155: logger.log(BasicLevel.INFO, "Thread2: getObjectById");
156: BasicA ba = (BasicA) pm2.getObjectById(id, true);
157: Assert.assertNotNull("Object not found", ba);
158: logger.log(BasicLevel.INFO, "Thread2: write");
159: ba.writeF2(ba.readF2() + 1);
160: logger.log(BasicLevel.INFO, "Thread2: write done");
161: logger.log(BasicLevel.INFO, "Thread2: commit");
162: pm2.currentTransaction().commit();
163: pm2.close();
164: }
165: });
166:
167: // end transaction 1
168: logger.log(BasicLevel.INFO, "Thread1: commit");
169: pm1.currentTransaction().commit();
170: pm1.close();
171:
172: assertUnlock(t);
173:
174: // clean up
175: pm = pmf.getPersistenceManager();
176: pm.currentTransaction().begin();
177: ba = (BasicA) pm.getObjectById(id, true);
178: Assert.assertNotNull("Object not found", ba);
179: Assert.assertEquals("Bad f1 value", "1", ba.readF1());
180: Assert.assertEquals("Bad f2 value", 3, ba.readF2());
181: pm.deletePersistent(ba);
182: pm.currentTransaction().commit();
183: pm.close();
184: }
185:
186: public void testWriteConcurrentRead() {
187: logger.log(BasicLevel.INFO, "test write concurrent read");
188: // setup
189: BasicA ba = new BasicA();
190: ba.writeF1("1");
191: ba.writeF2(2);
192: PersistenceManager pm = pmf.getPersistenceManager();
193: pm.currentTransaction().begin();
194: pm.makePersistent(ba);
195: final Object id = pm.getObjectId(ba);
196: Assert.assertNotNull("Null object identifier", id);
197: pm.currentTransaction().commit();
198: pm.close();
199:
200: ba = null;
201:
202: // begin transaction 1
203: PersistenceManager pm1 = pmf.getPersistenceManager();
204: logger.log(BasicLevel.INFO, "Thread1: begin");
205: pm1.currentTransaction().begin();
206: logger.log(BasicLevel.INFO, "Thread1: getObjectById");
207: ba = (BasicA) pm1.getObjectById(id, true);
208: Assert.assertNotNull("Object not found", ba);
209: logger.log(BasicLevel.INFO, "Thread1: write");
210: ba.writeF2(ba.readF2() + 1);
211: logger.log(BasicLevel.INFO, "Thread1: write done");
212:
213: // begin transaction 2
214: Thread t = assertLock(new Runnable() {
215: public void run() {
216: PersistenceManager pm2 = pmf.getPersistenceManager();
217: logger.log(BasicLevel.INFO, "Thread2: begin");
218: pm2.currentTransaction().begin();
219: logger.log(BasicLevel.INFO, "Thread2: getObjectById");
220: BasicA ba = (BasicA) pm2.getObjectById(id, true);
221: Assert.assertNotNull("Object not found", ba);
222: logger.log(BasicLevel.INFO, "Thread2: read");
223: ba.readF2();
224: logger.log(BasicLevel.INFO, "Thread2: read done");
225: logger.log(BasicLevel.INFO, "Thread2: commit");
226: pm2.currentTransaction().commit();
227: pm2.close();
228: }
229: });
230:
231: // end transaction 1
232: logger.log(BasicLevel.INFO, "Thread1: commit");
233: pm1.currentTransaction().commit();
234: pm1.close();
235:
236: assertUnlock(t);
237:
238: // clean up
239: pm = pmf.getPersistenceManager();
240: pm.currentTransaction().begin();
241: ba = (BasicA) pm.getObjectById(id, true);
242: Assert.assertNotNull("Object not found", ba);
243: Assert.assertEquals("Bad f1 value", "1", ba.readF1());
244: Assert.assertEquals("Bad f2 value", 3, ba.readF2());
245: pm.deletePersistent(ba);
246: pm.currentTransaction().commit();
247: pm.close();
248: }
249:
250: public void testWriteConcurrentRead2() {
251: logger.log(BasicLevel.INFO, "test write concurrent read 2");
252: // setup
253: BasicA ba = new BasicA();
254: ba.writeF1("1");
255: ba.writeF2(2);
256: PersistenceManager pm = pmf.getPersistenceManager();
257: pm.currentTransaction().begin();
258: pm.makePersistent(ba);
259: final Object id = pm.getObjectId(ba);
260: Assert.assertNotNull("Null object identifier", id);
261: pm.currentTransaction().commit();
262: pm.close();
263:
264: ba = null;
265:
266: // begin transaction 1
267: PersistenceManager pm1 = pmf.getPersistenceManager();
268: logger.log(BasicLevel.INFO, "Thread1: begin");
269: pm1.currentTransaction().begin();
270: logger.log(BasicLevel.INFO, "Thread1: getObjectById");
271: BasicA ba1 = (BasicA) pm1.getObjectById(id, true);
272: Assert.assertNotNull("Object not found", ba1);
273:
274: // begin transaction 2
275: Thread t = new Thread((new Runnable() {
276: public void run() {
277: PersistenceManager pm2 = pmf.getPersistenceManager();
278: logger.log(BasicLevel.INFO, "Thread2: begin");
279: pm2.currentTransaction().begin();
280: logger.log(BasicLevel.INFO, "Thread2: getObjectById");
281: BasicA ba2 = (BasicA) pm2.getObjectById(id, true);
282: Assert.assertNotNull("Object not found", ba2);
283: logger.log(BasicLevel.INFO, "Thread2: read");
284: ba2.readF2();
285: logger.log(BasicLevel.INFO, "Thread2: read done");
286: logger.log(BasicLevel.INFO, "Thread2: commit");
287: pm2.currentTransaction().commit();
288: pm2.close();
289: }
290: }));
291: t.start();
292:
293: // end transaction 1
294: logger.log(BasicLevel.INFO, "Thread1: write");
295: ba1.writeF2(ba1.readF2() + 1);
296: logger.log(BasicLevel.INFO, "Thread1: write done");
297: logger.log(BasicLevel.INFO, "Thread1: commit");
298: pm1.currentTransaction().commit();
299: pm1.close();
300:
301: assertUnlock(t);
302:
303: // clean up
304: pm = pmf.getPersistenceManager();
305: pm.currentTransaction().begin();
306: ba = (BasicA) pm.getObjectById(id, true);
307: Assert.assertNotNull("Object not found", ba);
308: Assert.assertEquals("Bad f1 value", "1", ba.readF1());
309: Assert.assertEquals("Bad f2 value", 3, ba.readF2());
310: pm.deletePersistent(ba);
311: pm.currentTransaction().commit();
312: pm.close();
313: }
314:
315: public void testConcurrentWrites() {
316: logger.log(BasicLevel.INFO, "test concurrent writes");
317: // setup
318: BasicA ba = new BasicA();
319: ba.writeF1("1");
320: ba.writeF2(2);
321: PersistenceManager pm = pmf.getPersistenceManager();
322: pm.currentTransaction().begin();
323: pm.makePersistent(ba);
324: final Object id = pm.getObjectId(ba);
325: Assert.assertNotNull("Null object identifier", id);
326: pm.currentTransaction().commit();
327: pm.close();
328:
329: ba = null;
330:
331: // begin transaction 1
332: PersistenceManager pm1 = pmf.getPersistenceManager();
333: logger.log(BasicLevel.INFO, "Thread1: begin");
334: pm1.currentTransaction().begin();
335: logger.log(BasicLevel.INFO, "Thread1: getObjectById");
336: ba = (BasicA) pm1.getObjectById(id, true);
337: Assert.assertNotNull("Object not found", ba);
338: logger.log(BasicLevel.INFO, "Thread1: write");
339: ba.writeF2(ba.readF2() + 1);
340: logger.log(BasicLevel.INFO, "Thread1: write done");
341:
342: // begin transaction 2
343: Thread t = assertLock(new Runnable() {
344: public void run() {
345: PersistenceManager pm2 = pmf.getPersistenceManager();
346: try {
347: logger.log(BasicLevel.INFO, "Thread2: begin");
348: pm2.currentTransaction().begin();
349: logger.log(BasicLevel.INFO,
350: "Thread2: getObjectById");
351: BasicA ba = (BasicA) pm2.getObjectById(id, true);
352: Assert.assertNotNull("Object not found", ba);
353: logger.log(BasicLevel.INFO, "Thread2: write");
354: ba.writeF2(ba.readF2() + 1);
355: logger.log(BasicLevel.INFO, "Thread2: write done");
356:
357: logger.log(BasicLevel.INFO, "Thread2: commit");
358: pm2.currentTransaction().commit();
359: } catch (JDOFatalException e) {
360:
361: } finally {
362: pm2.close();
363: }
364: }
365: });
366:
367: // end transaction 1
368: logger.log(BasicLevel.INFO, "Thread1: commit");
369: pm1.currentTransaction().commit();
370: pm1.close();
371:
372: // end transaction 2
373: assertUnlock(t);
374:
375: // clean up
376: pm = pmf.getPersistenceManager();
377: pm.currentTransaction().begin();
378: ba = (BasicA) pm.getObjectById(id, true);
379: Assert.assertNotNull("Object not found", ba);
380: Assert.assertEquals("Bad f1 value", "1", ba.readF1());
381: Assert.assertEquals("Bad f2 value", 4, ba.readF2());
382: pm.deletePersistent(ba);
383: pm.currentTransaction().commit();
384: pm.close();
385: }
386:
387: public void testConcurrentWrites2() {
388: logger.log(BasicLevel.INFO, "test concurrent writes 2");
389: // setup
390: BasicA ba = new BasicA();
391: ba.writeF1("1");
392: ba.writeF2(2);
393: PersistenceManager pm = pmf.getPersistenceManager();
394: pm.currentTransaction().begin();
395: pm.makePersistent(ba);
396: final Object id = pm.getObjectId(ba);
397: Assert.assertNotNull("Null object identifier", id);
398: pm.currentTransaction().commit();
399: pm.close();
400:
401: ba = null;
402:
403: // begin transaction 1
404: PersistenceManager pm1 = pmf.getPersistenceManager();
405: logger.log(BasicLevel.INFO, "Thread1: begin");
406: pm1.currentTransaction().begin();
407: logger.log(BasicLevel.INFO, "Thread1: getObjectById");
408: ba = (BasicA) pm1.getObjectById(id, true);
409: Assert.assertNotNull("Object not found", ba);
410:
411: // begin transaction 2
412: Thread t = assertLock(new Runnable() {
413: public void run() {
414: PersistenceManager pm2 = pmf.getPersistenceManager();
415: try {
416: logger.log(BasicLevel.INFO, "Thread2: begin");
417: pm2.currentTransaction().begin();
418: logger.log(BasicLevel.INFO,
419: "Thread2: getObjectById");
420: BasicA ba = (BasicA) pm2.getObjectById(id, true);
421: Assert.assertNotNull("Object not found", ba);
422: logger.log(BasicLevel.INFO, "Thread2: write");
423: ba.writeF2(ba.readF2() + 1);
424: logger.log(BasicLevel.INFO, "Thread2: write done");
425:
426: logger.log(BasicLevel.INFO, "Thread2: commit");
427: pm2.currentTransaction().commit();
428: } catch (JDOFatalException e) {
429: } finally {
430: pm2.close();
431: }
432: }
433: });
434:
435: // end transaction 1
436: logger.log(BasicLevel.INFO, "Thread1: write");
437: boolean ok = true;
438: try {
439: ba.writeF2(ba.readF2() + 1);
440: ok = true;
441: logger.log(BasicLevel.INFO, "Thread1: write done");
442: logger.log(BasicLevel.INFO, "Thread1: commit");
443: pm1.currentTransaction().commit();
444: } catch (JDOException e) {
445: logger.log(BasicLevel.INFO, "Thread1: write aborted"
446: + ExceptionHelper.getNested(e).getMessage());
447: ok = false;
448: } finally {
449: pm1.close();
450: }
451: assertUnlock(t);
452:
453: // clean up
454: pm = pmf.getPersistenceManager();
455: pm.currentTransaction().begin();
456: ba = (BasicA) pm.getObjectById(id, true);
457: Assert.assertNotNull("Object not found", ba);
458: Assert.assertEquals("Bad f1 value", "1", ba.readF1());
459: Assert.assertEquals("Bad f2 value", (ok ? 4 : 3), ba.readF2());
460: pm.deletePersistent(ba);
461: pm.currentTransaction().commit();
462: pm.close();
463: }
464:
465: private Thread assertLock(Runnable r) {
466: Thread t = new Thread(r);
467: t.start();
468: try {
469: t.join(5000);
470: } catch (InterruptedException _) {
471: // ignored
472: }
473: assertTrue(t.isAlive());
474: logger.log(BasicLevel.INFO, "Thread2: locked");
475: return t;
476: }
477:
478: private void assertUnlock(Thread t) {
479: try {
480: t.join(5000);
481: } catch (InterruptedException _) {
482: // ignored
483: }
484: assertTrue(!t.isAlive());
485: }
486: }
|