package org.reldb.rel.v0.storage;
import org.reldb.rel.exceptions.ExceptionFatal;
import com.sleepycat.je.*;
public abstract class TransactionRunner {
private final static int retryLimit = 10;
public abstract Object run(Transaction txn) throws Throwable;
public Object execute(RelDatabase environment) throws Throwable {
boolean ran = false;
Object returnvalue = null;
RelTransaction txn = null;
for (int attempt=0; attempt<retryLimit; attempt++) {
txn = environment.beginTransaction();
try {
returnvalue = run(txn.getTransaction());
ran = true;
break;
} catch (com.sleepycat.je.LockTimeoutException lte) {
environment.rollbackTransaction(txn);
Thread.sleep((long)(Math.random() * 5000.0));
} catch (Throwable t) {
environment.rollbackTransaction(txn);
throw t;
}
}
if (ran)
environment.commitTransaction(txn);
else
throw new ExceptionFatal("RS0379: Transaction " + txn + " attempted " + retryLimit + " times. Aborted.");
return returnvalue;
}
}