in server/src/main/java/org/apache/seata/server/coordinator/DefaultCore.java [373:437]
public boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException {
boolean success = true;
// start rollback event
MetricsPublisher.postSessionDoingEvent(globalSession, retrying);
if (globalSession.isSaga()) {
success = getCore(BranchType.SAGA).doGlobalRollback(globalSession, retrying);
} else {
List<BranchSession> branchSessions = globalSession.getReverseSortedBranches();
Boolean result = SessionHelper.forEach(branchSessions, branchSession -> {
BranchStatus currentBranchStatus = branchSession.getStatus();
if (currentBranchStatus == BranchStatus.PhaseOne_Failed) {
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
return CONTINUE;
}
// skip the branch session if not retry
if (retrying && BranchStatus.STOP_RETRY.equals(currentBranchStatus)) {
return CONTINUE;
}
try {
BranchStatus branchStatus = branchRollback(globalSession, branchSession);
if (isXaerNotaTimeout(globalSession, branchStatus)) {
LOGGER.info("Rollback branch XAER_NOTA retry timeout, xid = {} branchId = {}", globalSession.getXid(), branchSession.getBranchId());
branchStatus = BranchStatus.PhaseTwo_Rollbacked;
}
switch (branchStatus) {
case PhaseTwo_Rollbacked:
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
LOGGER.info("Rollback branch transaction successfully, xid = {} branchId = {}", globalSession.getXid(), branchSession.getBranchId());
return CONTINUE;
case PhaseTwo_RollbackFailed_Unretryable:
SessionHelper.endRollbackFailed(globalSession, retrying);
LOGGER.error("Rollback branch transaction fail and stop retry, xid = {} branchId = {}", globalSession.getXid(), branchSession.getBranchId());
return false;
default:
LOGGER.error("Rollback branch transaction fail and will retry, xid = {} branchId = {}", globalSession.getXid(), branchSession.getBranchId());
if (!retrying) {
globalSession.queueToRetryRollback();
}
return false;
}
} catch (Exception ex) {
StackTraceLogger.error(LOGGER, ex,
"Rollback branch transaction exception, xid = {} ,branchId = {} ,retrying={} ,exception = {}, global rollback failed",
new String[] {globalSession.getXid(), String.valueOf(branchSession.getBranchId()), String.valueOf(retrying), ex.getMessage()});
if (!retrying) {
globalSession.queueToRetryRollback();
}
throw new TransactionException(ex);
}
}, PARALLEL_HANDLE_BRANCH && branchSessions.size() >= 2);
// Return if the result is not null
if (result != null) {
return result;
}
}
// In db mode, lock and branch data residual problems may occur.
// Therefore, execution needs to be delayed here and cannot be executed synchronously.
if (success) {
SessionHelper.endRollbacked(globalSession, retrying);
LOGGER.info("Rollback global transaction successfully, xid = {}.", globalSession.getXid());
}
return success;
}