use of io.seata.saga.statelang.domain.StateInstance in project seata by seata.
the class DefaultStatusDecisionStrategy method setMachineStatusBasedOnStateListAndException.
/**
* set machine status based on state list
*
* @param stateMachineInstance
* @param stateList
* @return
*/
public static void setMachineStatusBasedOnStateListAndException(StateMachineInstance stateMachineInstance, List<StateInstance> stateList, Exception exp) {
boolean hasSetStatus = false;
boolean hasSuccessUpdateService = false;
if (CollectionUtils.isNotEmpty(stateList)) {
boolean hasUnsuccessService = false;
for (int i = stateList.size() - 1; i >= 0; i--) {
StateInstance stateInstance = stateList.get(i);
if (stateInstance.isIgnoreStatus() || stateInstance.isForCompensation()) {
continue;
}
if (ExecutionStatus.UN.equals(stateInstance.getStatus())) {
stateMachineInstance.setStatus(ExecutionStatus.UN);
hasSetStatus = true;
} else if (ExecutionStatus.SU.equals(stateInstance.getStatus())) {
if (DomainConstants.STATE_TYPE_SERVICE_TASK.equals(stateInstance.getType())) {
if (stateInstance.isForUpdate() && !stateInstance.isForCompensation()) {
hasSuccessUpdateService = true;
}
}
} else if (ExecutionStatus.SK.equals(stateInstance.getStatus())) {
// ignore
} else {
hasUnsuccessService = true;
}
}
if (!hasSetStatus && hasUnsuccessService) {
if (hasSuccessUpdateService) {
stateMachineInstance.setStatus(ExecutionStatus.UN);
} else {
stateMachineInstance.setStatus(ExecutionStatus.FA);
}
hasSetStatus = true;
}
}
if (!hasSetStatus) {
setMachineStatusBasedOnException(stateMachineInstance, exp, hasSuccessUpdateService);
}
}
use of io.seata.saga.statelang.domain.StateInstance in project seata by seata.
the class DbAndReportTcStateLogStore method generateRetryStateInstanceId.
/**
* generate retry state instance id based on original state instance id
* ${originalStateInstanceId}.${retryCount}
* @param stateInstance
* @return
*/
private String generateRetryStateInstanceId(StateInstance stateInstance) {
String originalStateInstId = stateInstance.getStateIdRetriedFor();
int maxIndex = 1;
Map<String, StateInstance> stateInstanceMap = stateInstance.getStateMachineInstance().getStateMap();
StateInstance originalStateInst = stateInstanceMap.get(stateInstance.getStateIdRetriedFor());
while (StringUtils.hasLength(originalStateInst.getStateIdRetriedFor())) {
originalStateInst = stateInstanceMap.get(originalStateInst.getStateIdRetriedFor());
int idIndex = getIdIndex(originalStateInst.getId(), ".");
maxIndex = idIndex > maxIndex ? idIndex : maxIndex;
maxIndex++;
}
if (originalStateInst != null) {
originalStateInstId = originalStateInst.getId();
}
return originalStateInstId + "." + maxIndex;
}
use of io.seata.saga.statelang.domain.StateInstance in project seata by seata.
the class DbAndReportTcStateLogStore method getStateMachineInstance.
@Override
public StateMachineInstance getStateMachineInstance(String stateMachineInstanceId) {
StateMachineInstance stateMachineInstance = selectOne(stateLogStoreSqls.getGetStateMachineInstanceByIdSql(dbType), RESULT_SET_TO_STATE_MACHINE_INSTANCE, stateMachineInstanceId);
if (stateMachineInstance == null) {
return null;
}
List<StateInstance> stateInstanceList = queryStateInstanceListByMachineInstanceId(stateMachineInstanceId);
for (StateInstance stateInstance : stateInstanceList) {
stateMachineInstance.putStateInstance(stateInstance.getId(), stateInstance);
}
deserializeParamsAndException(stateMachineInstance);
return stateMachineInstance;
}
use of io.seata.saga.statelang.domain.StateInstance in project seata by seata.
the class DbAndReportTcStateLogStore method branchReport.
protected void branchReport(StateInstance stateInstance, ProcessContext context) {
if (sagaTransactionalTemplate != null) {
StateMachineConfig stateMachineConfig = (StateMachineConfig) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONFIG);
if (stateMachineConfig instanceof DbStateMachineConfig && !((DbStateMachineConfig) stateMachineConfig).isSagaBranchRegisterEnable()) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("sagaBranchRegisterEnable = false, skip branch report. state[" + stateInstance.getName() + "]");
}
return;
}
BranchStatus branchStatus = null;
// find out the original state instance, only the original state instance is registered on the server, and its status should
// be reported.
StateInstance originalStateInst = null;
if (StringUtils.hasLength(stateInstance.getStateIdRetriedFor())) {
if (isUpdateMode(stateInstance, context)) {
originalStateInst = stateInstance;
} else {
originalStateInst = findOutOriginalStateInstanceOfRetryState(stateInstance);
}
if (ExecutionStatus.SU.equals(stateInstance.getStatus())) {
branchStatus = BranchStatus.PhaseTwo_Committed;
} else if (ExecutionStatus.FA.equals(stateInstance.getStatus()) || ExecutionStatus.UN.equals(stateInstance.getStatus())) {
branchStatus = BranchStatus.PhaseOne_Failed;
} else {
branchStatus = BranchStatus.Unknown;
}
} else if (StringUtils.hasLength(stateInstance.getStateIdCompensatedFor())) {
if (isUpdateMode(stateInstance, context)) {
originalStateInst = stateInstance.getStateMachineInstance().getStateMap().get(stateInstance.getStateIdCompensatedFor());
} else {
originalStateInst = findOutOriginalStateInstanceOfCompensateState(stateInstance);
}
}
if (originalStateInst == null) {
originalStateInst = stateInstance;
}
if (branchStatus == null) {
if (ExecutionStatus.SU.equals(originalStateInst.getStatus()) && originalStateInst.getCompensationStatus() == null) {
branchStatus = BranchStatus.PhaseTwo_Committed;
} else if (ExecutionStatus.SU.equals(originalStateInst.getCompensationStatus())) {
branchStatus = BranchStatus.PhaseTwo_Rollbacked;
} else if (ExecutionStatus.FA.equals(originalStateInst.getCompensationStatus()) || ExecutionStatus.UN.equals(originalStateInst.getCompensationStatus())) {
branchStatus = BranchStatus.PhaseTwo_RollbackFailed_Retryable;
} else if ((ExecutionStatus.FA.equals(originalStateInst.getStatus()) || ExecutionStatus.UN.equals(originalStateInst.getStatus())) && originalStateInst.getCompensationStatus() == null) {
branchStatus = BranchStatus.PhaseOne_Failed;
} else {
branchStatus = BranchStatus.Unknown;
}
}
try {
StateMachineInstance machineInstance = stateInstance.getStateMachineInstance();
GlobalTransaction globalTransaction = getGlobalTransaction(machineInstance, context);
if (globalTransaction == null) {
throw new EngineExecutionException("Global transaction is not exists", FrameworkErrorCode.ObjectNotExists);
}
sagaTransactionalTemplate.branchReport(globalTransaction.getXid(), Long.parseLong(originalStateInst.getId()), branchStatus, null);
} catch (TransactionException e) {
LOGGER.error("Report branch status to server error: {}, StateMachine:{}, StateName:{}, XID: {}, branchId: {}, branchStatus:{}," + " Reason:{} ", e.getCode(), originalStateInst.getStateMachineInstance().getStateMachine().getName(), originalStateInst.getName(), originalStateInst.getStateMachineInstance().getId(), originalStateInst.getId(), branchStatus, e.getMessage(), e);
} catch (ExecutionException e) {
LOGGER.error("Report branch status to server error: {}, StateMachine:{}, StateName:{}, XID: {}, branchId: {}, branchStatus:{}," + " Reason:{} ", e.getCode(), originalStateInst.getStateMachineInstance().getStateMachine().getName(), originalStateInst.getName(), originalStateInst.getStateMachineInstance().getId(), originalStateInst.getId(), branchStatus, e.getMessage(), e);
}
}
}
use of io.seata.saga.statelang.domain.StateInstance in project seata by seata.
the class DbAndReportTcStateLogStore method isUpdateMode.
private boolean isUpdateMode(StateInstance stateInstance, ProcessContext context) {
DefaultStateMachineConfig stateMachineConfig = (DefaultStateMachineConfig) context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONFIG);
StateInstruction instruction = context.getInstruction(StateInstruction.class);
ServiceTaskStateImpl state = (ServiceTaskStateImpl) instruction.getState(context);
StateMachine stateMachine = stateInstance.getStateMachineInstance().getStateMachine();
if (StringUtils.hasLength(stateInstance.getStateIdRetriedFor())) {
if (null != state.isRetryPersistModeUpdate()) {
return state.isRetryPersistModeUpdate();
} else if (null != stateMachine.isRetryPersistModeUpdate()) {
return stateMachine.isRetryPersistModeUpdate();
}
return stateMachineConfig.isSagaRetryPersistModeUpdate();
} else if (StringUtils.hasLength(stateInstance.getStateIdCompensatedFor())) {
// find if this compensate has been executed
for (int i = 0; i < stateInstance.getStateMachineInstance().getStateList().size(); i++) {
StateInstance aStateInstance = stateInstance.getStateMachineInstance().getStateList().get(i);
if (aStateInstance.isForCompensation() && aStateInstance.getName().equals(stateInstance.getName())) {
if (null != state.isCompensatePersistModeUpdate()) {
return state.isCompensatePersistModeUpdate();
} else if (null != stateMachine.isCompensatePersistModeUpdate()) {
return stateMachine.isCompensatePersistModeUpdate();
}
return stateMachineConfig.isSagaCompensatePersistModeUpdate();
}
}
return false;
}
return false;
}
Aggregations