1 package org.jboss.cache.transaction; 2 3 4 import EDU.oswego.cs.dl.util.concurrent.Latch; 5 import junit.framework.AssertionFailedError; 6 import junit.framework.Test; 7 import junit.framework.TestCase; 8 import junit.framework.TestSuite; 9 import org.jboss.cache.Cache; 10 import org.jboss.cache.CacheImpl; 11 import org.jboss.cache.DummyTransactionManagerLookup; 12 import org.jboss.cache.Fqn; 13 import org.jboss.cache.config.Configuration; 14 import org.jboss.cache.config.Configuration.CacheMode; 15 import org.jboss.cache.factories.DefaultCacheFactory; 16 import org.jboss.cache.lock.IsolationLevel; 17 import org.jboss.cache.lock.TimeoutException; 18 19 import javax.transaction.NotSupportedException ; 20 import javax.transaction.SystemException ; 21 import javax.transaction.Transaction ; 22 23 24 30 31 public class IsolationLevelReadCommittedTest extends TestCase 32 { 33 34 private Cache cache = null; 35 private final Fqn FQN = Fqn.fromString("/a/b/c"); 36 private final Fqn PARENT_FQN = FQN.getParent(); 37 private final String KEY = "key"; 38 private final String 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 46 { 47 super.setUp(); 48 49 writerFailed = false; 50 readerFailed = false; 51 52 writerError = null; 53 readerError = null; 54 55 Configuration config = new Configuration(); 56 config.setCacheMode(CacheMode.LOCAL); 57 config.setIsolationLevel(IsolationLevel.READ_COMMITTED); 58 config.setLockAcquisitionTimeout(1000); 59 config.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName()); 60 cache = DefaultCacheFactory.getInstance().createCache(config); 61 } 62 63 64 protected void tearDown() throws Exception 65 { 66 super.tearDown(); 67 68 cache.stop(); 69 cache.destroy(); 70 cache = null; 71 } 72 73 74 80 public void testReadCommitted() throws Exception 81 { 82 final Latch readerCanRead = new Latch(); 83 final Latch readerDone = new Latch(); 84 final Latch writerCanWrite = new Latch(); 85 final Latch writerCanRollback = new Latch(); 86 final Latch writerDone = new Latch(); 87 88 cache.put(FQN, KEY, VALUE); 89 assertEquals(VALUE, cache.get(FQN, KEY)); 90 91 94 Thread readerThread = new Thread (new Runnable () 95 { 96 public void run() 97 { 98 Transaction tx = null; 99 try 100 { 101 tx = startTransaction(); 102 103 assertEquals("Could not read node with expected value!", VALUE, cache.get(FQN, KEY)); 105 106 writerCanWrite.release(); 107 108 readerCanRead.acquire(); 111 112 try 113 { 114 assertEquals("thread w/ read lock can see subsequent uncommitted changes!!", VALUE, cache.get(FQN, KEY)); 116 } 117 catch (TimeoutException good) 118 { 119 } 121 122 writerCanRollback.release(); 124 125 assertEquals("Could not read node with expected value!", VALUE, cache.get(FQN, KEY)); 127 } 128 catch (AssertionFailedError e) 129 { 130 readerError = e; 131 } 132 catch (Throwable t) 133 { 134 t.printStackTrace(); 135 readerFailed = true; 136 } 137 finally 138 { 139 System.out.println("reader thread exits"); 140 if (tx != null) 141 { 142 try { tx.commit(); } catch (Exception e) {} 143 } 144 writerCanWrite.release(); 145 writerCanRollback.release(); 146 readerDone.release(); 147 } 148 } 149 }, "READER"); 150 readerThread.start(); 151 152 154 Thread writerThread = new Thread (new Runnable () 155 { 156 public void run() 157 { 158 try 159 { 160 writerCanWrite.attempt(3000); 162 163 Transaction tx2 = startTransaction(); 164 165 cache.put(FQN, KEY, "this-shouldnt-be-visible"); 167 168 readerCanRead.release(); 170 171 writerCanRollback.attempt(3000); 173 174 System.out.println("rolling back"); 175 176 tx2.rollback(); 177 } 178 catch (AssertionFailedError e) 179 { 180 writerError = e; 181 } 182 catch (Throwable t) 183 { 184 t.printStackTrace(); 185 writerFailed = true; 186 } 187 finally 188 { 189 System.out.println("writer thread exits"); 190 readerCanRead.release(); 191 writerDone.release(); 192 } 193 } 194 }, "WRITER"); 195 writerThread.start(); 196 197 readerDone.acquire(); 199 writerDone.acquire(); 200 201 if (readerError != null) 203 { 204 throw readerError; 205 } 206 207 if (writerError != null) 208 { 209 throw writerError; 210 } 211 212 if (readerFailed) 213 { 214 fail("The reader thread exited incorrectly. Watch the log for previous stack traces"); 215 } 216 217 if (writerFailed) 218 { 219 fail("The writer thread exited incorrectly. Watch the log for previous stack traces"); 220 } 221 } 222 223 230 public void testNodeRemoved() throws Exception 231 { 232 final Latch readerCanRead = new Latch(); 233 final Latch readerDone = new Latch(); 234 final Latch writerDone = new Latch(); 235 236 cache.put(FQN, KEY, VALUE); 237 assertEquals(VALUE, cache.get(FQN, KEY)); 238 239 241 Thread writerThread = new Thread (new Runnable () 242 { 243 public void run() 244 { 245 try 246 { 247 Transaction tx = startTransaction(); 248 249 cache.removeNode(PARENT_FQN); 251 252 readerCanRead.release(); 254 255 readerDone.acquire(); 256 257 tx.commit(); 258 } 259 catch (AssertionFailedError e) 260 { 261 writerError = e; 262 } 263 catch (Throwable t) 264 { 265 t.printStackTrace(); 266 writerFailed = true; 267 } 268 finally 269 { 270 System.out.println("writer thread exits"); 271 readerCanRead.release(); 272 writerDone.release(); 273 } 274 } 275 }, "WRITER"); 276 writerThread.start(); 277 278 try 279 { 280 readerCanRead.acquire(); 283 284 assertEquals("2nd thread cannot see uncommitted changes", 286 VALUE, cache.get(FQN, KEY)); 287 } 288 catch (TimeoutException t) 289 { 290 } 292 finally 293 { 294 System.out.println("reader thread exits"); 295 readerDone.release(); 296 } 297 298 writerDone.acquire(); 300 301 assertNull("Node was removed", ((CacheImpl) cache).get(FQN)); 302 303 305 if (writerError != null) 306 { 307 throw writerError; 308 } 309 310 if (writerFailed) 311 { 312 fail("The writer thread exited incorrectly. Watch the log for previous stack traces"); 313 } 314 315 } 316 317 private Transaction startTransaction() throws SystemException , NotSupportedException 318 { 319 DummyTransactionManager mgr = DummyTransactionManager.getInstance(); 320 mgr.begin(); 321 return mgr.getTransaction(); 322 } 323 324 325 public static Test suite() 326 { 327 328 return new TestSuite(IsolationLevelReadCommittedTest.class); 329 330 } 331 332 } 333 334 | Popular Tags |