final CountDownLatch secondCanRead = new CountDownLatch(1);
final CountDownLatch secondDone = new CountDownLatch(1);
final CountDownLatch firstCanRollback = new CountDownLatch(1);
final CountDownLatch firstDone = new CountDownLatch(1);
final Fqn PARENT = Fqn.fromString("/a");
// start a first thread and a transaction
Thread firstThread = new Thread(new Runnable()
{
public void run()
{
try
{
TransactionManager tm = startTransaction();
// Create an empty parent node and a node with data
Fqn a1 = Fqn.fromRelativeElements(PARENT, "1");
cache.put(a1, KEY, VALUE);
// notify the second thread it can write
secondCanWrite.countDown();
// wait until the second thread writes and allows me to rollback or until I timeout
firstCanRollback.await(3000, TimeUnit.MILLISECONDS);
tm.rollback();
assertNull("a1 empty", cache.get(a1, KEY));
// notify the reading thread
secondCanRead.countDown();
}
catch (AssertionError e)
{
writerError = e;
}
catch (Throwable t)
{
t.printStackTrace();
writerFailed = true;
}
finally
{
secondCanWrite.countDown();
secondCanRead.countDown();
firstDone.countDown();
}
}
}, "FIRST");
firstThread.start();
// start a second thread; no transaction is necessary here
Thread secondThread = new Thread(new Runnable()
{
public void run()
{
try
{
// wait until the first thread has created PARENT and a child
secondCanWrite.await();
// create a second child under parent
Fqn a2 = Fqn.fromRelativeElements(PARENT, "2");
try
{
cache.put(a2, KEY, VALUE);
}
catch (TimeoutException good)