private async Task RootMethodProceed(CompensableMethodContext compensableMethodContext) { var allDelayCancelExceptionTypes = new HashSet <Type>(); allDelayCancelExceptionTypes.AddRange(this._delayCancelExceptionTypes); allDelayCancelExceptionTypes.AddRange(compensableMethodContext.Compensable.DelayCancelExceptionTypes); using (var transaction = _transactionManager.Begin(compensableMethodContext.GetUniqueIdentity())) { try { await compensableMethodContext.MethodInvocation.ProceedAsync(); } catch (Exception ex) { if (!_transactionManager.IsDelayCancelException(ex, allDelayCancelExceptionTypes)) { _logger.LogError(string.Format("compensable transaction trying failed. transaction content:{0} ", JsonConvert.SerializeObject(transaction))); await _transactionManager.RollbackAsync(); } throw ex; } await _transactionManager.CommitAsync(); } }
public async Task InterceptAsync(IMethodInvocation invocation) { if (!CompensableHelper.IsCompensableMethod(invocation.Method)) { await invocation.ProceedAsync(); return; } CompensableMethodContext compensableMethodContext = new CompensableMethodContext(invocation, _serviceProvider); var isTransactionActive = _transactionManager.IsTransactionActive(); if (!TransactionUtils.IsLegalTransactionContext(isTransactionActive, compensableMethodContext)) { throw new TransactionException($"no available compensable transaction, the method {compensableMethodContext.MethodInfo.Name} is illegal"); } switch (compensableMethodContext.GetMethodRole(isTransactionActive)) { case MethodRole.ROOT: await RootMethodProceed(compensableMethodContext); break; case MethodRole.PROVIDER: await ProviderMethodProceed(compensableMethodContext); break; default: await invocation.ProceedAsync(); break; } }
private async Task ProviderMethodProceed(CompensableMethodContext compensableMethodContext) { //It designed to reuse API by calling difference method base on incoming transaction status from remote calling switch (compensableMethodContext.TransactionContext.Status) { case TransactionStatus.TRYING: _transactionManager.PropagationNewBegin(compensableMethodContext.TransactionContext); await compensableMethodContext.MethodInvocation.ProceedAsync(); break; case TransactionStatus.CONFIRMING: try { using (_transactionManager.PropagationExistBegin(compensableMethodContext.TransactionContext)) { await _transactionManager.CommitAsync(); } } catch (Exception ex) { _logger.LogWarning(ex, "the transaction has been committed"); //the transaction has been commit, ignore it. } break; case TransactionStatus.CANCELLING: try { using (_transactionManager.PropagationExistBegin(compensableMethodContext.TransactionContext)) { await _transactionManager.RollbackAsync(); } } catch (Exception ex) { _logger.LogWarning(ex, "the transaction has been cancelled"); //the transaction has been rollback, ignore it. } break; } }