task.getOwner(),
task.getStartTime(),
waitSize);
task.incrementTryCount();
Transaction transaction = null;
try {
// setup the transaction state
TransactionHandle handle =
transactionCoordinator.createTransaction(unbounded);
transaction = handle.getTransaction();
ContextResolver.setCurrentTransaction(transaction);
try {
// notify the profiler and access coordinator
profileCollectorHandle.noteTransactional(
transaction.getId());
accessCoordinator.
notifyNewTransaction(transaction,
task.getStartTime(),
task.getTryCount());
// run the task in the new transactional context
task.getTask().run();
} finally {
// regardless of the outcome, always clear the current
// transaction state before proceeding...
ContextResolver.clearCurrentTransaction(transaction);
}
// try to commit the transaction...note that there's the
// chance that the application code masked the orginal
// cause of a failure, so we'll check for that first,
// re-throwing the root cause in that case
if (transaction.isAborted()) {
throw transaction.getAbortCause();
}
handle.commit();
// the task completed successfully, so we're done
profileCollectorHandle.finishTask(task.getTryCount());
task.setDone(null);
return true;
} catch (InterruptedException ie) {
// make sure the transaction was aborted
if (!transaction.isAborted()) {
transaction.abort(ie);
}
profileCollectorHandle.finishTask(task.getTryCount(), ie);
// if the task didn't finish because of the interruption
// then we want to note that and possibly re-queue the
// task to run in a usable thread
if (task.setInterrupted() && retryOnInterruption) {
if (!handoffRetry(task, ie)) {
// if the task couldn't be re-queued, then there's
// nothing left to do but drop it
task.setDone(ie);
if (logger.isLoggable(Level.WARNING)) {
logger.logThrow(Level.WARNING, ie, "dropping " +
"an interrupted task: {0}" +
task);
}
}
}
// always re-throw the interruption
throw ie;
} catch (Throwable t) {
// make sure the transaction was aborted
if ((transaction != null) && (!transaction.isAborted())) {
transaction.abort(t);
}
profileCollectorHandle.finishTask(task.getTryCount(), t);
// some error occurred, so see if we should re-try
if (!shouldRetry(task, t)) {
// the task is not being re-tried