[jboss-jira] [JBoss JIRA] Closed: (JBCACHE-740) Optimistic Locking Scheme: Occasional IllegalStateExceptions on commit

Manik Surtani (JIRA) jira-events at jboss.com
Wed Jan 17 10:43:55 EST 2007


     [ http://jira.jboss.com/jira/browse/JBCACHE-740?page=all ]

Manik Surtani closed JBCACHE-740.
---------------------------------

    Resolution: Cannot Reproduce Bug

> Optimistic Locking Scheme: Occasional IllegalStateExceptions on commit
> ----------------------------------------------------------------------
>
>                 Key: JBCACHE-740
>                 URL: http://jira.jboss.com/jira/browse/JBCACHE-740
>             Project: JBoss Cache
>          Issue Type: Bug
>      Security Level: Public(Everyone can see) 
>    Affects Versions: 1.4.0.GA
>         Environment: Linux 2.6.15-26-686 #1 SMP PREEMPT Thu Aug 3 03:13:28 UTC 2006 i686 GNU/Linux
> java version "1.5.0_06"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
> Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode, sharing)
> JOTM 2.0.10
> JUnit 3.8.1
>            Reporter: Carsten Krebs
>         Assigned To: Manik Surtani
>             Fix For: 2.0.0.BETA1
>
>         Attachments: MultithreadedTxTest.java
>
>
> The unit test below reproduces "occasional" IllegalStateExceptions (s.b.) on commiting a transaction.  This test tries to modify the same node at the same time by different threads in different transactions using the optimistic locking scheme.
> java.lang.IllegalStateException: there is already a writer holding the lock: GlobalTransaction:<null>:43
> 	at org.jboss.cache.lock.LockMap.setWriterIfNotNull(LockMap.java:96)
> 	at org.jboss.cache.lock.IdentityLock.acquireWriteLock(IdentityLock.java:204)
> 	at org.jboss.cache.Node.acquireWriteLock(Node.java:431)
> 	at org.jboss.cache.Node.acquire(Node.java:386)
> 	at org.jboss.cache.interceptors.OptimisticLockingInterceptor.lockNodes(OptimisticLockingInterceptor.java:149)
> 	at org.jboss.cache.interceptors.OptimisticLockingInterceptor.invoke(OptimisticLockingInterceptor.java:76)
> 	at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
> 	at org.jboss.cache.interceptors.TxInterceptor.runPreparePhase(TxInterceptor.java:804)
> 	at org.jboss.cache.interceptors.TxInterceptor$LocalSynchronizationHandler.beforeCompletion(TxInterceptor.java:1069)
> 	at org.jboss.cache.interceptors.OrderedSynchronizationHandler.beforeCompletion(OrderedSynchronizationHandler.java:75)
> 	at org.objectweb.jotm.SubCoordinator.doBeforeCompletion(SubCoordinator.java:1487)
> 	at org.objectweb.jotm.SubCoordinator.commit_one_phase(SubCoordinator.java:416)
> 	at org.objectweb.jotm.TransactionImpl.commit(TransactionImpl.java:239)
> 	at OptimisticLockingTest$Worker.run(OptimisticLockingTest.java:135)
> The Cache Config:
> -------------------------
> <?xml version="1.0" encoding="UTF-8"?>
> <server>
>     <mbean code="org.jboss.cache.TreeCache" name="jboss.cache:service=TreeCache">
> 		<attribute name="NodeLockingScheme">OPTIMISTIC</attribute>	
>         <attribute name="CacheMode">LOCAL</attribute>
>     </mbean>
> </server>   
> The Unit Test:
> -------------------
> import javax.transaction.Transaction;
> import javax.transaction.TransactionManager;
> import junit.framework.TestCase;
> import org.jboss.cache.CacheException;
> import org.jboss.cache.PropertyConfigurator;
> import org.jboss.cache.TransactionManagerLookup;
> import org.jboss.cache.TreeCache;
> import org.objectweb.jotm.Current;
> import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
> /**
>  * OptimisticLockingTest
>  */
> public class OptimisticLockingTest extends TestCase {
> 	private static final String NODE_PATH = "/path/node";
> 	private static final String KEY = "key";
> 	private static final Current jotm = new Current();
> 	private TreeCache cache;
> 	protected void setUp() throws Exception {
> 		super.setUp();
> 		cache = new TreeCache();
> 		final PropertyConfigurator config = new PropertyConfigurator();
> 		cache.setTransactionManagerLookup(new TransactionManagerLookup() {
> 			public TransactionManager getTransactionManager() throws Exception {
> 				return Current.getTransactionManager();
> 			}
> 		});
> 		config.configure(cache, this.getClass().getResourceAsStream(
> 				"/cache-config.xml"));
> 		cache.startService();
> 	}
> 	public void testSimultanWrite() throws Exception {
> 		for (int i = 2; i < 20; i++) {
> 			System.out.println(">> testing simultaneous writes with " + i
> 					+ " threads...");
> 			testSimultanWrite(i);
> 		}
> 	}
> 	public void testSimultanWrite(final int _numThreads) throws Exception {
> 		final CyclicBarrier barrier = new CyclicBarrier(_numThreads);
> 		Worker[] workers = new Worker[_numThreads];
> 		for (int i = 0; i < workers.length; i++) {
> 			workers[i] = new Worker();
> 			workers[i].barrier = barrier;
> 			workers[i].value = "worker" + i;
> 			if (i == 0) {
> 				workers[i].isMaster = true;
> 			}
> 			workers[i].start();
> 		}
> 		for (int i = 0; i < workers.length; i++) {
> 			workers[i].join();
> 		}
> 		assertNull(workers[0].exception);
> 		for (int i = 0; i < workers.length; i++) {
> 			assertNull("rollback failed", workers[i].rollbackException);
> 		}
> 		for (int i = 1; i < workers.length; i++) {
> 			assertNotNull("missing exception", workers[i].exception);
> 			assertTrue("exception is not of type CacheException",
> 					workers[i].exception.getCause() instanceof CacheException);
> 		}
> 		assertEquals("worker0", cache.get(NODE_PATH, KEY));
> 		cache.getTransactionManager().begin();
> 		cache.remove(NODE_PATH);
> 		cache.getTransactionManager().commit();
> 	}
> 	private class Worker extends Thread {
> 		private CyclicBarrier barrier;
> 		private Exception exception;
> 		private Exception rollbackException;
> 		private String value;
> 		private boolean isMaster;
> 		/**
> 		 * @see java.lang.Thread#run()
> 		 */
> 		public void run() {
> 			final TransactionManager txManager = cache.getTransactionManager();
> 			Transaction tx = null;
> 			try {
> 				// wait for all threads started
> 				barrier.barrier();
> 				if (isMaster) {
> 					txManager.begin();
> 					cache.put(NODE_PATH, KEY, value);
> 					// lets the other threads start writing
> 					barrier.barrier();
> 					// wait for other threads to their modification
> 					barrier.barrier();
> 					// commit first
> 					tx = txManager.getTransaction();
> 					tx.commit();
> 					// lets the other threads commit
> 					barrier.barrier();
> 				} else {
> 					// wait for master to start transaction
> 					barrier.barrier();
> 					txManager.begin();
> 					cache.put(NODE_PATH, KEY, value);
> 					// signal modification
> 					barrier.barrier();
> 					// wait for master to commit transaction
> 					barrier.barrier();
> 					tx = txManager.getTransaction();
> 					tx.commit();
> 				}
> 			} catch (Exception e) {
> 				exception = e;
> 				try {
> 					tx.rollback();
> 				} catch (Exception e1) {
> 					rollbackException = e1;
> 				}
> 			}
> 		}
> 	}
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the jboss-jira mailing list