}
if (status == Status.STATUS_MARKED_ROLLBACK) {
rollbackResources(resourceManagers);
if (timedout) {
throw new RollbackException("Transaction timout");
} else {
throw new RollbackException("Unable to commit: transaction marked for rollback");
}
}
synchronized (this) {
if (status == Status.STATUS_ACTIVE) {
if (this.resourceManagers.size() == 0) {
// nothing to commit
status = Status.STATUS_COMMITTED;
} else if (this.resourceManagers.size() == 1) {
// one-phase commit decision
status = Status.STATUS_COMMITTING;
} else {
// start prepare part of two-phase
status = Status.STATUS_PREPARING;
}
}
// resourceManagers is now immutable
}
// no-phase
if (resourceManagers.size() == 0) {
synchronized (this) {
status = Status.STATUS_COMMITTED;
}
return;
}
// one-phase
if (resourceManagers.size() == 1) {
TransactionBranch manager = (TransactionBranch) resourceManagers.getFirst();
try {
manager.getCommitter().commit(manager.getBranchId(), true);
synchronized (this) {
status = Status.STATUS_COMMITTED;
}
return;
} catch (XAException e) {
synchronized (this) {
status = Status.STATUS_ROLLEDBACK;
}
throw (RollbackException) new RollbackException("Error during one-phase commit").initCause(e);
}
}
// two-phase
boolean willCommit = internalPrepare();
// notify the RMs
if (willCommit) {
commitResources(resourceManagers);
} else {
rollbackResources(resourceManagers);
throw new RollbackException("Unable to commit");
}
} finally {
afterCompletion();
synchronized (this) {
status = Status.STATUS_NO_TRANSACTION;