Unexpected (?) TimeoutException
jacek187 Aug 16, 2007 6:15 PMCould anybody tel me, why I got TimeoutException when 2 Threads are executing this code?
for (int x = 0; x < 1000; x++) { tm.begin(); System.out.println("R" + Thread.currentThread().getName()); //inside transaction cache.remove("/a"); System.out.println("AR" + Thread.currentThread().getName()); tm.commit(); //outside transaction System.out.println("P" + Thread.currentThread().getName()); cache.putObject("/a/b/c/d", "text"+x); System.out.println("AP" + Thread.currentThread().getName()); }
Console Output:
RThread:0
RThread:1
ARThread:1
ARThread:0
PThread:1
PThread:0
APThread:1
RThread:1
org.jboss.cache.lock.TimeoutException: failure acquiring lock: fqn=/a, caller=GlobalTransaction::3, lock=read owners=[GlobalTransaction::3], write owner=GlobalTransaction::5 (org.jboss.cache.lock.LockStrategyReadCommitted@d02b51)
at org.jboss.cache.Node.acquire(Node.java:500)
at org.jboss.cache.interceptors.PessimisticLockInterceptor.acquireNodeLock(PessimisticLockInterceptor.java:379)
at org.jboss.cache.interceptors.PessimisticLockInterceptor.lock(PessimisticLockInterceptor.java:307)
at
(...)
Complete code:
package org.jboss.cache.aop; import java.util.ArrayList; import java.util.List; import javax.transaction.TransactionManager; import junit.framework.TestCase; import org.jboss.cache.DummyTransactionManagerLookup; import org.jboss.cache.TreeCache; import org.jboss.cache.lock.IsolationLevel; public class ConcurentPutRemoveTest extends TestCase { private TransactionManager tm; public ConcurentPutRemoveTest(String s) { super(s); } private PojoCache cache; protected void setUp() throws Exception { cache = new PojoCache(); cache.setCacheMode(TreeCache.LOCAL); cache.setIsolationLevel(IsolationLevel.READ_COMMITTED); cache.setTransactionManagerLookup(new DummyTransactionManagerLookup()); cache.setLockAcquisitionTimeout(10000); cache.create(); cache.start(); tm = cache.getTransactionManager(); } protected void tearDown() throws Exception { super.tearDown(); cache.stop(); cache.destroy(); } public void testLock() throws Exception { List<SeparateThread> threads = new ArrayList<SeparateThread>(); for (int x = 0; x < 2; x++) { SeparateThread t = new SeparateThread(x); threads.add(t); t.start(); } for (SeparateThread separateThread : threads) { separateThread.join(); if (separateThread.getException() != null) { throw separateThread.getException(); } } } private class SeparateThread extends Thread { Exception e = null; private int num = 0; public SeparateThread(int num) { this.num = num; } public Exception getException() { return e; } public void run() { Thread.currentThread().setName("Thread:" + num); try { for (int x = 0; x < 1000; x++) { tm.begin(); System.out.println("R" + Thread.currentThread().getName()); //inside transaction cache.remove("/a"); System.out.println("AR" + Thread.currentThread().getName()); tm.commit(); //outside transaction System.out.println("P" + Thread.currentThread().getName()); cache.putObject("/a/b/c/d", "text"+x); System.out.println("AP" + Thread.currentThread().getName()); } } catch (Exception e) { this.e = e; } } } }