KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > cache > transaction > IsolationLevelReadCommittedNodeCreationRollbackTest


1 /*
2  * JBoss, Home of Professional Open Source
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.cache.transaction;
8
9 import EDU.oswego.cs.dl.util.concurrent.Latch;
10 import junit.framework.AssertionFailedError;
11 import junit.framework.Test;
12 import junit.framework.TestCase;
13 import junit.framework.TestSuite;
14 import org.jboss.cache.CacheImpl;
15 import org.jboss.cache.DummyTransactionManagerLookup;
16 import org.jboss.cache.Fqn;
17 import org.jboss.cache.config.Configuration;
18 import org.jboss.cache.lock.IsolationLevel;
19 import org.jboss.cache.lock.TimeoutException;
20
21 import javax.transaction.NotSupportedException JavaDoc;
22 import javax.transaction.SystemException JavaDoc;
23 import javax.transaction.Transaction JavaDoc;
24
25 /**
26  * Tests READ_COMMITED isolation level.
27  *
28  * @author <a HREF="mailto:ovidiu@jboss.org">Ovidiu Feodorov</a>
29  * @version $Id: IsolationLevelReadCommittedNodeCreationRollbackTest.java,v 1.4 2006/12/30 17:49:53 msurtani Exp $
30  */

31
32 public class IsolationLevelReadCommittedNodeCreationRollbackTest extends TestCase
33 {
34
35    private CacheImpl cache = null;
36    private final Fqn FQN = Fqn.fromString("/a/b/c");
37    private final String JavaDoc KEY = "key";
38    private final String JavaDoc VALUE = "value";
39
40    private volatile boolean writerFailed;
41    private volatile boolean readerFailed;
42    private volatile AssertionFailedError writerError;
43    private volatile AssertionFailedError readerError;
44
45    protected void setUp() throws Exception JavaDoc
46    {
47       super.setUp();
48
49       writerFailed = false;
50       readerFailed = false;
51
52       writerError = null;
53       readerError = null;
54
55       cache = new CacheImpl();
56       cache.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL);
57       cache.getConfiguration().setIsolationLevel(IsolationLevel.READ_COMMITTED);
58       cache.getConfiguration().setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
59       cache.start();
60    }
61
62
63    protected void tearDown() throws Exception JavaDoc
64    {
65       super.tearDown();
66
67       cache.stop();
68       cache.destroy();
69       cache = null;
70    }
71
72
73    public void testNodeCreationRollback() throws Exception JavaDoc
74    {
75       final Latch secondCanWrite = new Latch();
76       final Latch secondCanRead = new Latch();
77       final Latch secondDone = new Latch();
78       final Latch firstCanRollback = new Latch();
79       final Latch firstDone = new Latch();
80
81       final Fqn PARENT = Fqn.fromString("/a");
82
83       // start a first thread and a transaction
84

85       Thread JavaDoc firstThread = new Thread JavaDoc(new Runnable JavaDoc()
86       {
87          public void run()
88          {
89             try
90             {
91                Transaction JavaDoc tx = startTransaction();
92
93                System.out.println("Writing /a/1");
94
95                // Create an empty parent node and a node with data
96
Fqn a1 = new Fqn(PARENT, "1");
97                cache.put(a1, KEY, VALUE);
98
99                // notify the second thread it can write
100
secondCanWrite.release();
101
102                // wait until the second thread writes and allows me to rollback or until I timeout
103
firstCanRollback.attempt(3000);
104
105                System.out.println("rolling back");
106
107                tx.rollback();
108
109                assertNull("a1 empty", cache.get(a1, KEY));
110
111                // notify the reading thread
112
secondCanRead.release();
113             }
114             catch (AssertionFailedError e)
115             {
116                writerError = e;
117             }
118             catch (Throwable JavaDoc t)
119             {
120                t.printStackTrace();
121                writerFailed = true;
122             }
123             finally
124             {
125                System.out.println("first thread exits");
126                secondCanWrite.release();
127                secondCanRead.release();
128                firstDone.release();
129             }
130          }
131       }, "FIRST");
132       firstThread.start();
133
134       // start a second thread; no transaction is necessary here
135

136       Thread JavaDoc secondThread = new Thread JavaDoc(new Runnable JavaDoc()
137       {
138          public void run()
139          {
140             try
141             {
142                // wait until the first thread has created PARENT and a child
143
secondCanWrite.acquire();
144
145                System.out.println("writing a2");
146
147                // create a second child under parent
148
Fqn a2 = new Fqn(PARENT, "2");
149                try
150                {
151                   cache.put(a2, KEY, VALUE);
152                }
153                catch (TimeoutException good)
154                {
155                   // first thread locked us out of parent
156
System.out.println("Prevented from writing a2 -- " +
157                           good.getLocalizedMessage());
158                   return;
159                }
160
161                // let the first thread know it can rollback
162
firstCanRollback.release();
163
164                // wait until the first thread rolls back.
165
secondCanRead.acquire();
166
167                // I should still see the value I put
168
assertEquals("Known issue JBCACHE-407 -- write lock not acquired on " +
169                        "creation of an empty node", VALUE, cache.get(a2, KEY));
170             }
171             catch (AssertionFailedError e)
172             {
173                readerError = e;
174             }
175             catch (Throwable JavaDoc t)
176             {
177                t.printStackTrace();
178                readerFailed = true;
179             }
180             finally
181             {
182                System.out.println("second thread exits");
183                firstCanRollback.release();
184                secondDone.release();
185             }
186          }
187       }, "SECOND");
188       secondThread.start();
189
190       // wait for both threads to finish
191
secondDone.acquire();
192       firstDone.acquire();
193
194       // If any assertion failed, throw on the AssertionFailedError
195
if (readerError != null)
196       {
197          throw readerError;
198       }
199
200       if (writerError != null)
201       {
202          throw writerError;
203       }
204
205       if (readerFailed)
206       {
207          fail("The second thread exited incorrectly. Watch the log for previous stack traces");
208       }
209
210       if (writerFailed)
211       {
212          fail("The first thread exited incorrectly. Watch the log for previous stack traces");
213       }
214    }
215
216
217    private Transaction JavaDoc startTransaction() throws SystemException JavaDoc, NotSupportedException JavaDoc
218    {
219       DummyTransactionManager mgr = DummyTransactionManager.getInstance();
220       mgr.begin();
221       return mgr.getTransaction();
222    }
223
224
225    public static Test suite()
226    {
227
228       return new TestSuite(IsolationLevelReadCommittedNodeCreationRollbackTest.class);
229
230    }
231
232
233 }
234
Popular Tags