[jboss-jira] [JBoss JIRA] Updated: (JBCACHE-740) Optimistic Locking Scheme: Occasional IllegalStateExceptions on commit
Manik Surtani (JIRA)
jira-events at jboss.com
Tue Jan 9 15:53:28 EST 2007
[ http://jira.jboss.com/jira/browse/JBCACHE-740?page=all ]
Manik Surtani updated JBCACHE-740:
----------------------------------
Fix Version/s: 2.0.0.BETA1
(was: 2.0.0.GA)
> 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
>
>
> 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