Search in sources :

Example 1 with BusinessActionContext

use of io.seata.rm.tcc.api.BusinessActionContext in project seata by seata.

the class ActionInterceptorHandler method proceed.

/**
 * Handler the TCC Aspect
 *
 * @param method         the method
 * @param arguments      the arguments
 * @param businessAction the business action
 * @param targetCallback the target callback
 * @return map map
 * @throws Throwable the throwable
 */
public Map<String, Object> proceed(Method method, Object[] arguments, String xid, TwoPhaseBusinessAction businessAction, Callback<Object> targetCallback) throws Throwable {
    Map<String, Object> ret = new HashMap<>(4);
    // TCC name
    String actionName = businessAction.name();
    BusinessActionContext actionContext = new BusinessActionContext();
    actionContext.setXid(xid);
    // set action name
    actionContext.setActionName(actionName);
    // Creating Branch Record
    String branchId = doTccActionLogStore(method, arguments, businessAction, actionContext);
    actionContext.setBranchId(branchId);
    // MDC put branchId
    MDC.put(RootContext.MDC_KEY_BRANCH_ID, branchId);
    // set the parameter whose type is BusinessActionContext
    Class<?>[] types = method.getParameterTypes();
    int argIndex = 0;
    for (Class<?> cls : types) {
        if (cls.getName().equals(BusinessActionContext.class.getName())) {
            arguments[argIndex] = actionContext;
            break;
        }
        argIndex++;
    }
    // the final parameters of the try method
    ret.put(Constants.TCC_METHOD_ARGUMENTS, arguments);
    // the final result
    ret.put(Constants.TCC_METHOD_RESULT, targetCallback.execute());
    return ret;
}
Also used : HashMap(java.util.HashMap) BusinessActionContext(io.seata.rm.tcc.api.BusinessActionContext)

Example 2 with BusinessActionContext

use of io.seata.rm.tcc.api.BusinessActionContext in project seata by seata.

the class TCCResourceManager method branchCommit.

/**
 * TCC branch commit
 *
 * @param branchType
 * @param xid             Transaction id.
 * @param branchId        Branch id.
 * @param resourceId      Resource id.
 * @param applicationData Application data bind with this branch.
 * @return BranchStatus
 * @throws TransactionException TransactionException
 */
@Override
public BranchStatus branchCommit(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException {
    TCCResource tccResource = (TCCResource) tccResourceCache.get(resourceId);
    if (tccResource == null) {
        throw new ShouldNeverHappenException(String.format("TCC resource is not exist, resourceId: %s", resourceId));
    }
    Object targetTCCBean = tccResource.getTargetBean();
    Method commitMethod = tccResource.getCommitMethod();
    if (targetTCCBean == null || commitMethod == null) {
        throw new ShouldNeverHappenException(String.format("TCC resource is not available, resourceId: %s", resourceId));
    }
    try {
        // BusinessActionContext
        BusinessActionContext businessActionContext = getBusinessActionContext(xid, branchId, resourceId, applicationData);
        Object ret = commitMethod.invoke(targetTCCBean, businessActionContext);
        LOGGER.info("TCC resource commit result : {}, xid: {}, branchId: {}, resourceId: {}", ret, xid, branchId, resourceId);
        boolean result;
        if (ret != null) {
            if (ret instanceof TwoPhaseResult) {
                result = ((TwoPhaseResult) ret).isSuccess();
            } else {
                result = (boolean) ret;
            }
        } else {
            result = true;
        }
        return result ? BranchStatus.PhaseTwo_Committed : BranchStatus.PhaseTwo_CommitFailed_Retryable;
    } catch (Throwable t) {
        String msg = String.format("commit TCC resource error, resourceId: %s, xid: %s.", resourceId, xid);
        LOGGER.error(msg, t);
        return BranchStatus.PhaseTwo_CommitFailed_Retryable;
    }
}
Also used : ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) Method(java.lang.reflect.Method) BusinessActionContext(io.seata.rm.tcc.api.BusinessActionContext)

Example 3 with BusinessActionContext

use of io.seata.rm.tcc.api.BusinessActionContext in project seata by seata.

the class TCCResourceManager method getBusinessActionContext.

/**
 * transfer tcc applicationData to BusinessActionContext
 *
 * @param xid             the xid
 * @param branchId        the branch id
 * @param resourceId      the resource id
 * @param applicationData the application data
 * @return business action context
 */
protected BusinessActionContext getBusinessActionContext(String xid, long branchId, String resourceId, String applicationData) {
    // transfer tcc applicationData to Context
    Map tccContext = StringUtils.isBlank(applicationData) ? new HashMap() : (Map) JSON.parse(applicationData);
    Map actionContextMap = (Map) tccContext.get(Constants.TCC_ACTION_CONTEXT);
    BusinessActionContext businessActionContext = new BusinessActionContext(xid, String.valueOf(branchId), actionContextMap);
    businessActionContext.setActionName(resourceId);
    return businessActionContext;
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Map(java.util.Map) BusinessActionContext(io.seata.rm.tcc.api.BusinessActionContext)

Example 4 with BusinessActionContext

use of io.seata.rm.tcc.api.BusinessActionContext in project jboot by yangfuhai.

the class ActionInterceptorHandler method proceed.

/**
 * Handler the TCC Aspect
 *
 * @param method         the method
 * @param arguments      the arguments
 * @param businessAction the business action
 * @return map map
 * @throws Throwable the throwable
 */
public void proceed(Method method, Object[] arguments, String xid, TwoPhaseBusinessAction businessAction, Invocation invocation) {
    // TCC name
    String actionName = businessAction.name();
    BusinessActionContext actionContext = new BusinessActionContext();
    actionContext.setXid(xid);
    // set action name
    actionContext.setActionName(actionName);
    Class<?>[] types = method.getParameterTypes();
    Parameter[] parameters = invocation.getMethod().getParameters();
    int argIndex = 0;
    for (Class<?> cls : types) {
        if (cls.getName().equals(BusinessActionContext.class.getName())) {
            arguments[argIndex] = actionContext;
            break;
        }
        argIndex++;
    }
    // Creating Branch Record
    String branchId = doTccActionLogStore(method, parameters, arguments, businessAction, actionContext);
    try {
        registryResource(method, invocation.getTarget(), types, businessAction);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    actionContext.setBranchId(branchId);
    invocation.invoke();
}
Also used : Parameter(java.lang.reflect.Parameter) BusinessActionContext(io.seata.rm.tcc.api.BusinessActionContext)

Example 5 with BusinessActionContext

use of io.seata.rm.tcc.api.BusinessActionContext in project seata by seata.

the class TCCResourceManager method branchRollback.

/**
 * TCC branch rollback
 *
 * @param branchType      the branch type
 * @param xid             Transaction id.
 * @param branchId        Branch id.
 * @param resourceId      Resource id.
 * @param applicationData Application data bind with this branch.
 * @return BranchStatus
 * @throws TransactionException TransactionException
 */
@Override
public BranchStatus branchRollback(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException {
    TCCResource tccResource = (TCCResource) tccResourceCache.get(resourceId);
    if (tccResource == null) {
        throw new ShouldNeverHappenException(String.format("TCC resource is not exist, resourceId: %s", resourceId));
    }
    Object targetTCCBean = tccResource.getTargetBean();
    Method rollbackMethod = tccResource.getRollbackMethod();
    if (targetTCCBean == null || rollbackMethod == null) {
        throw new ShouldNeverHappenException(String.format("TCC resource is not available, resourceId: %s", resourceId));
    }
    try {
        // BusinessActionContext
        BusinessActionContext businessActionContext = getBusinessActionContext(xid, branchId, resourceId, applicationData);
        Object ret = rollbackMethod.invoke(targetTCCBean, businessActionContext);
        LOGGER.info("TCC resource rollback result : {}, xid: {}, branchId: {}, resourceId: {}", ret, xid, branchId, resourceId);
        boolean result;
        if (ret != null) {
            if (ret instanceof TwoPhaseResult) {
                result = ((TwoPhaseResult) ret).isSuccess();
            } else {
                result = (boolean) ret;
            }
        } else {
            result = true;
        }
        return result ? BranchStatus.PhaseTwo_Rollbacked : BranchStatus.PhaseTwo_RollbackFailed_Retryable;
    } catch (Throwable t) {
        String msg = String.format("rollback TCC resource error, resourceId: %s, xid: %s.", resourceId, xid);
        LOGGER.error(msg, t);
        return BranchStatus.PhaseTwo_RollbackFailed_Retryable;
    }
}
Also used : ShouldNeverHappenException(io.seata.common.exception.ShouldNeverHappenException) Method(java.lang.reflect.Method) BusinessActionContext(io.seata.rm.tcc.api.BusinessActionContext)

Aggregations

BusinessActionContext (io.seata.rm.tcc.api.BusinessActionContext)5 ShouldNeverHappenException (io.seata.common.exception.ShouldNeverHappenException)2 Method (java.lang.reflect.Method)2 HashMap (java.util.HashMap)2 Parameter (java.lang.reflect.Parameter)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1