KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > txn > LockManagerTest


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: LockManagerTest.java,v 1.45 2006/10/30 21:14:52 bostic Exp $
7  */

8
9 package com.sleepycat.je.txn;
10
11 import java.io.File JavaDoc;
12
13 import junit.framework.TestCase;
14
15 import com.sleepycat.je.DatabaseException;
16 import com.sleepycat.je.DeadlockException;
17 import com.sleepycat.je.EnvironmentConfig;
18 import com.sleepycat.je.config.EnvironmentParams;
19 import com.sleepycat.je.dbi.EnvironmentImpl;
20 import com.sleepycat.je.junit.JUnitThread;
21 import com.sleepycat.je.util.TestUtils;
22
23 public class LockManagerTest extends TestCase {
24     
25     private LockManager lockManager = null;
26     private Locker txn1;
27     private Locker txn2;
28     private Locker txn3;
29     private Locker txn4;
30     private Long JavaDoc nid;
31     private volatile int sequence;
32
33     private EnvironmentImpl env;
34     private File JavaDoc envHome;
35
36     public LockManagerTest() {
37         envHome = new File JavaDoc(System.getProperty(TestUtils.DEST_DIR));
38     }
39
40     public void setUp()
41     throws DatabaseException {
42
43         EnvironmentConfig envConfig = TestUtils.initEnvConfig();
44         envConfig.setConfigParam(EnvironmentParams.NODE_MAX.getName(), "6");
45         envConfig.setAllowCreate(true);
46     envConfig.setTransactional(true);
47         env = new EnvironmentImpl(envHome, envConfig);
48
49         TxnManager txnManager = env.getTxnManager();
50     lockManager = txnManager.getLockManager();
51     txn1 = new BasicLocker(env);
52     txn2 = new BasicLocker(env);
53     txn3 = new BasicLocker(env);
54     txn4 = new BasicLocker(env);
55     nid = new Long JavaDoc(1);
56     sequence = 0;
57     }
58
59     public void tearDown()
60     throws DatabaseException {
61
62         txn1.operationEnd();
63         txn2.operationEnd();
64         txn3.operationEnd();
65         txn4.operationEnd();
66         env.close();
67     }
68
69     public void testNegatives()
70         throws Exception JavaDoc {
71
72     try {
73         assertFalse(lockManager.isOwner(nid, txn1, LockType.READ));
74         assertFalse(lockManager.isOwner(nid, txn1, LockType.WRITE));
75         assertFalse(lockManager.isLocked(nid));
76         assertFalse(lockManager.isWaiter(nid, txn1));
77         lockManager.lock(1, txn1, LockType.READ, 0, false, null);
78
79         /* already holds this lock */
80         assertEquals(LockGrantType.EXISTING,
81                          lockManager.lock(1, txn1, LockType.READ, 0,
82                       false, null));
83         assertFalse(lockManager.isOwner(nid, txn2, LockType.READ));
84         assertFalse(lockManager.isOwner(nid, txn2, LockType.WRITE));
85         assertTrue(lockManager.isLocked(nid));
86         assertTrue(lockManager.nOwners(new Long JavaDoc(2)) == -1);
87         assertTrue(lockManager.nWaiters(new Long JavaDoc(2)) == -1);
88
89             /* lock 2 doesn't exist, shouldn't affect any the existing lock */
90         lockManager.release(2L, txn1);
91         assertTrue(lockManager.isLocked(nid));
92             
93             /* txn2 is not the owner, shouldn't release lock 1. */
94         lockManager.release(1L, txn2);
95         assertTrue(lockManager.isLocked(nid));
96             assertTrue(lockManager.isOwner(nid, txn1, LockType.READ));
97         assertTrue(lockManager.nOwners(nid) == 1);
98
99             /* Now really release. */
100         lockManager.release(1L, txn1);
101         assertFalse(lockManager.isLocked(nid));
102             assertFalse(lockManager.isOwner(nid, txn1, LockType.READ));
103         assertFalse(lockManager.nOwners(nid) == 1);
104
105         lockManager.lock(1, txn1, LockType.WRITE, 0, false, null);
106         /* holds write and subsequent request for READ is ok */
107         lockManager.lock(1, txn1, LockType.READ, 0, false, null);
108         /* already holds this lock */
109         assertTrue(lockManager.lock(1, txn1, LockType.WRITE,
110                     0, false, null) ==
111                LockGrantType.EXISTING);
112         assertFalse(lockManager.isWaiter(nid, txn1));
113     } catch (Exception JavaDoc e) {
114             e.printStackTrace();
115             throw e;
116     }
117     }
118
119     /**
120      * Acquire three read locks and make sure that they share nicely.
121      */

122     public void testMultipleReaders()
123     throws Throwable JavaDoc {
124
125     JUnitThread tester1 =
126         new JUnitThread("testMultipleReaders1") {
127         public void testBody() {
128             try {
129             lockManager.lock(1, txn1, LockType.READ, 0,
130                      false, null);
131             assertTrue
132                 (lockManager.isOwner(nid, txn1, LockType.READ));
133             sequence++;
134             while (sequence < 3) {
135                 Thread.yield();
136             }
137             lockManager.release(1L, txn1);
138             } catch (DatabaseException DBE) {
139                         DBE.printStackTrace();
140             fail("caught DatabaseException " + DBE);
141             }
142         }
143         };
144
145     JUnitThread tester2 =
146         new JUnitThread("testMultipleReaders2") {
147         public void testBody() {
148             try {
149             lockManager.lock(1, txn2, LockType.READ, 0,
150                      false, null);
151             assertTrue
152                 (lockManager.isOwner(nid, txn2, LockType.READ));
153             sequence++;
154             while (sequence < 3) {
155                 Thread.yield();
156             }
157             lockManager.release(1L, txn2);
158             } catch (DatabaseException DBE) {
159                         DBE.printStackTrace();
160             fail("caught DatabaseException " + DBE);
161             }
162         }
163         };
164
165     JUnitThread tester3 =
166         new JUnitThread("testMultipleReaders3") {
167         public void testBody() {
168             try {
169             lockManager.lock(1, txn3, LockType.READ, 0,
170                      false, null);
171             assertTrue
172                 (lockManager.isOwner(nid, txn3, LockType.READ));
173             sequence++;
174             while (sequence < 3) {
175                 Thread.yield();
176             }
177             lockManager.release(1L, txn3);
178             } catch (DatabaseException DBE) {
179                         DBE.printStackTrace();
180             fail("caught DatabaseException " + DBE);
181             }
182         }
183         };
184
185     tester1.start();
186     tester2.start();
187     tester3.start();
188     tester1.finishTest();
189     tester2.finishTest();
190     tester3.finishTest();
191     }
192
193     /**
194      * Grab two read locks, hold them, and make sure that a write lock
195      * waits for them to be released.
196      */

197     public void testMultipleReadersSingleWrite1()
198     throws Throwable JavaDoc {
199
200     JUnitThread tester1 =
201         new JUnitThread("testMultipleReaders1") {
202         public void testBody() {
203             try {
204             lockManager.lock(1, txn1, LockType.READ, 0,
205                      false, null);
206             assertTrue
207                 (lockManager.isOwner(nid, txn1, LockType.READ));
208             while (lockManager.nWaiters(nid) < 1) {
209                 Thread.yield();
210             }
211             assertTrue(lockManager.isWaiter(nid, txn3));
212             assertFalse(lockManager.isWaiter(nid, txn1));
213             lockManager.release(1L, txn1);
214             assertFalse
215                 (lockManager.isOwner(nid, txn1, LockType.READ));
216             } catch (DatabaseException DBE) {
217                         DBE.printStackTrace();
218             fail("caught DatabaseException " + DBE);
219             }
220         }
221         };
222
223     JUnitThread tester2 =
224         new JUnitThread("testMultipleReaders2") {
225         public void testBody() {
226             try {
227             lockManager.lock(1, txn2, LockType.READ, 0,
228                      false, null);
229             assertTrue
230                 (lockManager.isOwner(nid, txn2, LockType.READ));
231             while (lockManager.nWaiters(nid) < 1) {
232                 Thread.yield();
233             }
234             assertTrue(lockManager.isWaiter(nid, txn3));
235             lockManager.release(1L, txn2);
236             assertFalse
237                 (lockManager.isOwner(nid, txn2, LockType.READ));
238             } catch (DatabaseException DBE) {
239                         DBE.printStackTrace();
240             fail("caught DatabaseException " + DBE);
241             }
242         }
243         };
244
245     JUnitThread tester3 =
246         new JUnitThread("testMultipleReaders3") {
247         public void testBody() {
248             try {
249             while (lockManager.nOwners(nid) < 2) {
250                 Thread.yield();
251             }
252             lockManager.lock(1, txn3, LockType.WRITE, 0,
253                      false, null);
254             assertTrue
255                 (lockManager.isOwner(nid, txn3, LockType.WRITE));
256             } catch (DatabaseException DBE) {
257                         DBE.printStackTrace();
258             fail("caught DatabaseException " + DBE);
259             }
260         }
261         };
262
263     tester1.start();
264     tester2.start();
265     tester3.start();
266     tester1.finishTest();
267     tester2.finishTest();
268     tester3.finishTest();
269     }
270
271     /**
272      * Acquire two read locks, put a write locker behind the two
273      * read lockers, and then queue a read locker behind the writer.
274      * Ensure that the third reader is not granted until the writer
275      * releases the lock.
276      */

277     public void testMultipleReadersSingleWrite2()
278     throws Throwable JavaDoc {
279
280     JUnitThread tester1 =
281         new JUnitThread("testMultipleReaders1") {
282         public void testBody() {
283             try {
284             lockManager.lock(1, txn1, LockType.READ, 0,
285                      false, null);
286             assertTrue
287                 (lockManager.isOwner(nid, txn1, LockType.READ));
288             while (lockManager.nWaiters(nid) < 2) {
289                 Thread.yield();
290             }
291             lockManager.release(1L, txn1);
292             } catch (DatabaseException DBE) {
293                         DBE.printStackTrace();
294             fail("caught DatabaseException " + DBE);
295             }
296         }
297         };
298
299     JUnitThread tester2 =
300         new JUnitThread("testMultipleReaders2") {
301         public void testBody() {
302             try {
303             lockManager.lock(1, txn2, LockType.READ, 0,
304                      false, null);
305             assertTrue
306                 (lockManager.isOwner(nid, txn2, LockType.READ));
307             while (lockManager.nWaiters(nid) < 2) {
308                 Thread.yield();
309             }
310             lockManager.release(1L, txn2);
311             } catch (DatabaseException DBE) {
312                         DBE.printStackTrace();
313             fail("caught DatabaseException " + DBE);
314             }
315         }
316         };
317
318     JUnitThread tester3 =
319         new JUnitThread("testMultipleReaders3") {
320         public void testBody() {
321             try {
322             while (lockManager.nOwners(nid) < 2) {
323                 Thread.yield();
324             }
325             lockManager.lock(1, txn3, LockType.WRITE, 0,
326                      false, null);
327             while (lockManager.nWaiters(nid) < 1) {
328                 Thread.yield();
329             }
330             assertTrue
331                 (lockManager.isOwner(nid, txn3, LockType.WRITE));
332             lockManager.release(1L, txn3);
333             } catch (DatabaseException DBE) {
334                         DBE.printStackTrace();
335             fail("caught DatabaseException " + DBE);
336             }
337         }
338         };
339
340     JUnitThread tester4 =
341         new JUnitThread("testMultipleReaders4") {
342         public void testBody() {
343             try {
344             while (lockManager.nWaiters(nid) < 1) {
345                 Thread.yield();
346             }
347             lockManager.lock(1, txn4, LockType.READ, 0,
348                      false, null);
349             assertTrue
350                 (lockManager.isOwner(nid, txn4, LockType.READ));
351             lockManager.release(1L, txn4);
352             } catch (DatabaseException DBE) {
353                         DBE.printStackTrace();
354             fail("caught DatabaseException " + DBE);
355             }
356         }
357         };
358
359     tester1.start();
360     tester2.start();
361     tester3.start();
362     tester4.start();
363     tester1.finishTest();
364     tester2.finishTest();
365     tester3.finishTest();
366     tester4.finishTest();
367     }
368
369     /**
370      * Acquire two read locks for two transactions, then request a write
371      * lock for a third transaction. Then request a write lock for one
372      * of the first transactions that already has a read lock (i.e.
373      * request an upgrade lock). Make sure it butts in front of the
374      * existing wait lock.
375      */

376     public void testUpgradeLock()
377     throws Throwable JavaDoc {
378
379     JUnitThread tester1 =
380         new JUnitThread("testUpgradeLock1") {
381         public void testBody() {
382             try {
383             lockManager.lock(1, txn1, LockType.READ, 0,
384                      false, null);
385             assertTrue
386                 (lockManager.isOwner(nid, txn1, LockType.READ));
387             while (lockManager.nWaiters(nid) < 2) {
388                 Thread.yield();
389             }
390             lockManager.release(1L, txn1);
391             } catch (DatabaseException DBE) {
392                         DBE.printStackTrace();
393             fail("caught DatabaseException " + DBE);
394             }
395         }
396         };
397
398     JUnitThread tester2 =
399         new JUnitThread("testUpgradeLock2") {
400         public void testBody() {
401             try {
402             lockManager.lock(1, txn2, LockType.READ, 0,
403                      false, null);
404             assertTrue
405                 (lockManager.isOwner(nid, txn2, LockType.READ));
406             while (lockManager.nWaiters(nid) < 1) {
407                 Thread.yield();
408             }
409             lockManager.lock(1, txn2, LockType.WRITE, 0,
410                      false, null);
411             assertTrue(lockManager.nWaiters(nid) == 1);
412             lockManager.release(1L, txn2);
413             } catch (DatabaseException DBE) {
414                         DBE.printStackTrace();
415             fail("caught DatabaseException " + DBE);
416             }
417         }
418         };
419
420     JUnitThread tester3 =
421         new JUnitThread("testUpgradeLock3") {
422         public void testBody() {
423             try {
424             while (lockManager.nOwners(nid) < 2) {
425                 Thread.yield();
426             }
427             lockManager.lock(1, txn3, LockType.WRITE, 0,
428                      false, null);
429             assertTrue
430                 (lockManager.isOwner(nid, txn3, LockType.WRITE));
431             lockManager.release(1L, txn3);
432             } catch (DatabaseException DBE) {
433                         DBE.printStackTrace();
434             fail("caught DatabaseException " + DBE);
435             }
436         }
437         };
438
439     tester1.start();
440     tester2.start();
441     tester3.start();
442     tester1.finishTest();
443     tester2.finishTest();
444     tester3.finishTest();
445     }
446
447     /**
448      * Acquire a read lock, then request a write lock for a second
449      * transaction in non-blocking mode. Make sure it fails.
450      */

451     public void testNonBlockingLock1()
452     throws Throwable JavaDoc {
453
454     JUnitThread tester1 =
455         new JUnitThread("testNonBlocking1") {
456         public void testBody() {
457             try {
458             lockManager.lock(1, txn1, LockType.READ, 0,
459                      false, null);
460             assertTrue
461                 (lockManager.isOwner(nid, txn1, LockType.READ));
462             while (sequence < 1) {
463                 Thread.yield();
464             }
465             lockManager.release(1L, txn1);
466             } catch (DatabaseException DBE) {
467                         DBE.printStackTrace();
468             fail("caught DatabaseException " + DBE);
469             }
470         }
471         };
472
473     JUnitThread tester2 =
474         new JUnitThread("testNonBlocking2") {
475         public void testBody() {
476             try {
477             /* wait for tester1 */
478             while (lockManager.nOwners(nid) < 1) {
479                 Thread.yield();
480             }
481                         LockGrantType grant = lockManager.lock
482                             (1, txn2, LockType.WRITE, 0, true, null);
483                         assertSame(LockGrantType.DENIED, grant);
484             assertFalse
485                 (lockManager.isOwner(nid, txn2, LockType.WRITE));
486             assertFalse
487                 (lockManager.isOwner(nid, txn2, LockType.READ));
488             assertTrue(lockManager.nWaiters(nid) == 0);
489             assertTrue(lockManager.nOwners(nid) == 1);
490             sequence++;
491             /* wait for tester1 to release the lock */
492             while (lockManager.nOwners(nid) > 0) {
493                 Thread.yield();
494             }
495             assertTrue
496                 (lockManager.lock(1, txn2, LockType.WRITE, 0,
497                                               false, null) ==
498                  LockGrantType.NEW);
499             assertTrue
500                 (lockManager.isOwner(nid, txn2, LockType.WRITE));
501             assertTrue
502                 (lockManager.isOwner(nid, txn2, LockType.READ));
503             assertTrue(lockManager.nWaiters(nid) == 0);
504             assertTrue(lockManager.nOwners(nid) == 1);
505             lockManager.release(1L, txn2);
506             } catch (DatabaseException DBE) {
507                         DBE.printStackTrace();
508             fail("caught DatabaseException " + DBE);
509             }
510         }
511         };
512
513     tester1.start();
514     tester2.start();
515     tester1.finishTest();
516     tester2.finishTest();
517     }
518
519     /**
520      * Acquire a write lock, then request a read lock for a second
521      * transaction in non-blocking mode. Make sure it fails.
522      */

523     public void testNonBlockingLock2()
524     throws Throwable JavaDoc {
525
526     JUnitThread tester1 =
527         new JUnitThread("testNonBlocking1") {
528         public void testBody() {
529             try {
530             lockManager.lock(1, txn1, LockType.WRITE, 0,
531                      false, null);
532             assertTrue
533                 (lockManager.isOwner(nid, txn1, LockType.WRITE));
534             sequence++;
535             while (sequence < 2) {
536                 Thread.yield();
537             }
538             lockManager.release(1L, txn1);
539             } catch (DatabaseException DBE) {
540                         DBE.printStackTrace();
541             fail("caught DatabaseException " + DBE);
542             }
543         }
544         };
545
546     JUnitThread tester2 =
547         new JUnitThread("testNonBlocking2") {
548         public void testBody() {
549             try {
550             /* wait for tester1 */
551             while (sequence < 1) {
552                 Thread.yield();
553             }
554                         LockGrantType grant = lockManager.lock
555                             (1, txn2, LockType.READ, 0, true, null);
556                         assertSame(LockGrantType.DENIED, grant);
557             assertFalse
558                 (lockManager.isOwner(nid, txn2, LockType.READ));
559             assertFalse
560                 (lockManager.isOwner(nid, txn2, LockType.WRITE));
561             assertTrue(lockManager.nWaiters(nid) == 0);
562             assertTrue(lockManager.nOwners(nid) == 1);
563             sequence++;
564             /* wait for tester1 to release the lock */
565             while (lockManager.nOwners(nid) > 0) {
566                 Thread.yield();
567             }
568             assertTrue
569                 (lockManager.lock(1, txn2, LockType.READ, 0,
570                                               false, null) ==
571                  LockGrantType.NEW);
572             assertTrue
573                 (lockManager.isOwner(nid, txn2, LockType.READ));
574             assertFalse
575                 (lockManager.isOwner(nid, txn2, LockType.WRITE));
576             assertTrue(lockManager.nWaiters(nid) == 0);
577             assertTrue(lockManager.nOwners(nid) == 1);
578             lockManager.release(1L, txn2);
579             } catch (DatabaseException DBE) {
580                         DBE.printStackTrace();
581             fail("caught DatabaseException " + DBE);
582             }
583         }
584         };
585
586     tester1.start();
587     tester2.start();
588     tester1.finishTest();
589     tester2.finishTest();
590     }
591
592     /**
593      * Acquire a write lock, then request a read lock for a second
594      * transaction in blocking mode. Make sure it waits.
595      */

596     public void testWaitingLock()
597     throws Throwable JavaDoc {
598
599     JUnitThread tester1 =
600         new JUnitThread("testBlocking1") {
601         public void testBody() {
602             try {
603             lockManager.lock(1, txn1, LockType.WRITE, 0,
604                      false, null);
605             assertTrue
606                 (lockManager.isOwner(nid, txn1, LockType.WRITE));
607             sequence++;
608             while (sequence < 2) {
609                 Thread.yield();
610             }
611             lockManager.release(1L, txn1);
612             } catch (DatabaseException DBE) {
613                         DBE.printStackTrace();
614             fail("caught DatabaseException " + DBE);
615             }
616         }
617         };
618
619     JUnitThread tester2 =
620         new JUnitThread("testBlocking2") {
621         public void testBody() {
622             try {
623             /* wait for tester1 */
624             while (sequence < 1) {
625                 Thread.yield();
626             }
627             try {
628                 lockManager.lock(1, txn2, LockType.READ, 500,
629                                              false, null);
630                 fail("didn't time out");
631             } catch (DeadlockException e) {
632                             assertTrue(TestUtils.skipVersion(e).startsWith("Lock "));
633             }
634             assertFalse
635                 (lockManager.isOwner(nid, txn2, LockType.READ));
636             assertFalse
637                 (lockManager.isOwner(nid, txn2, LockType.WRITE));
638             assertTrue(lockManager.nWaiters(nid) == 0);
639             assertTrue(lockManager.nOwners(nid) == 1);
640             sequence++;
641             /* wait for tester1 to release the lock */
642             while (lockManager.nOwners(nid) > 0) {
643                 Thread.yield();
644             }
645             assertTrue
646                 (lockManager.lock(1, txn2, LockType.READ, 0,
647                                               false, null) ==
648                  LockGrantType.NEW);
649             assertTrue
650                 (lockManager.isOwner(nid, txn2, LockType.READ));
651             assertFalse
652                 (lockManager.isOwner(nid, txn2, LockType.WRITE));
653             assertTrue(lockManager.nWaiters(nid) == 0);
654             assertTrue(lockManager.nOwners(nid) == 1);
655             lockManager.release(1L, txn2);
656             } catch (DatabaseException DBE) {
657                         DBE.printStackTrace();
658             fail("caught DatabaseException " + DBE);
659             }
660         }
661         };
662
663     tester1.start();
664     tester2.start();
665     tester1.finishTest();
666     tester2.finishTest();
667     }
668
669     public void xtestDeadlock()
670     throws Throwable JavaDoc {
671
672     JUnitThread tester1 =
673         new JUnitThread("testDeadlock1") {
674         public void testBody() {
675             try {
676             lockManager.lock(1, txn1, LockType.WRITE, 0,
677                      false, null);
678             System.out.println("t1 has locked 1");
679             assertTrue
680                 (lockManager.isOwner(nid, txn1, LockType.WRITE));
681             sequence++; // bump to 1
682

683             /* wait for tester2 */
684             while (sequence < 2) {
685                 Thread.yield();
686             }
687
688             lockManager.lock(2, txn1, LockType.READ, 1000,
689                      false, null);
690             System.out.println("t1 about to sleep");
691             Thread.sleep(5000);
692
693             lockManager.release(1, txn1);
694             lockManager.release(2, txn1);
695             } catch (DatabaseException DBE) {
696                         DBE.printStackTrace();
697             fail("tester1 caught DatabaseException " + DBE);
698             } catch (InterruptedException JavaDoc IE) {
699             fail("tester1 caught InterruptedException " + IE);
700             }
701         }
702         };
703
704     JUnitThread tester2 =
705         new JUnitThread("testDeadlock2") {
706         public void testBody() {
707             try {
708             /* wait for tester1 */
709             while (sequence < 1) {
710                 Thread.yield();
711             }
712
713             lockManager.lock(2, txn2, LockType.WRITE, 0,
714                      false, null);
715             System.out.println("t2 has locked 2");
716
717             sequence++; // bump to 2
718

719             System.out.println("t2 about to lock 1");
720             lockManager.lock(1, txn2, LockType.READ, 1000,
721                      false, null);
722             System.out.println("t2 about to sleep");
723             Thread.sleep(5000);
724
725             lockManager.release(1, txn2);
726             lockManager.release(2, txn1);
727             } catch (DatabaseException DBE) {
728                         DBE.printStackTrace();
729             fail("tester2 caught DatabaseException " + DBE);
730             } catch (InterruptedException JavaDoc IE) {
731             fail("tester2 caught InterruptedException " + IE);
732             }
733         }
734         };
735
736     tester1.start();
737     tester2.start();
738     //tester3.start();
739
tester1.finishTest();
740     tester2.finishTest();
741     //tester3.finishTest();
742
}
743 }
744
Popular Tags