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;
}
}
}
}