private void CheckAndRunNext(TccRunningContext <TContext> rc) { if (rc != null) { _txState = rc.NextState; if (_txState == TccTransactionState.Confirmed) { if (_coordinator != null) { _coordinator.CloseTransaction(this); } _txCtx.Return(); return; } else if (_txState == TccTransactionState.Cancelled) { if (_coordinator != null) { _coordinator.CloseTransaction(this); } _txCtx.ThrowException("Transaction Cancelled", GetFirstError()); return; } else if (_txState == TccTransactionState.ConfirmFailed || _txState == TccTransactionState.CancelFailed) { if (_coordinator != null) { _coordinator.CloseTransaction(this); } _txCtx.ThrowException("Transaction Failed", GetFirstError()); return; } else { if (_coordinator != null) { _coordinator.UpdateTransaction(this); } } } lock (_syncRoot) { rc = GetRunningContext(); } _tracing.InfoFmt("NextRunningContext() = {0}", rc); rc.Run( delegate() { try { CheckAndRunNext(rc); } catch (Exception ex) { _tracing.Error(ex, "CheckAndRunNext() Failed"); _txCtx.ThrowException("TccTransaction.CheckAndRunNext() Failed", ex); } } ); }
private TccRunningContext <TContext> GetRunningContext() { TccRunningContext <TContext> rc = new TccRunningContext <TContext>(_context, _tracing); TccTransactionState nextState; switch (_txState) { case TccTransactionState.LockTrying: rc.AddWork(_lock, TccAction.Try); rc.SetNextState(TccTransactionState.Trying, TccTransactionState.Cancelling); break; case TccTransactionState.Trying: bool hasNext = false; foreach (var a in _works) { if (a.WorkState != TccWorkState.Tryed) { if (a.CanTry()) { rc.AddWork(a, TccAction.Try); } else { hasNext = true; } } } nextState = hasNext ? TccTransactionState.Trying : TccTransactionState.Confirming; rc.SetNextState(nextState, TccTransactionState.Cancelling); break; case TccTransactionState.Confirming: foreach (var a in _works) { if (a.WorkState != TccWorkState.Confirmed) { rc.AddWork(a, TccAction.Confirm); } } nextState = _lock != null ? TccTransactionState.LockConfirming :TccTransactionState.Confirmed; rc.SetNextState(nextState, TccTransactionState.ConfirmFailed); break; case TccTransactionState.LockConfirming: rc.AddWork(_lock, TccAction.Confirm); rc.SetNextState(TccTransactionState.Confirmed, TccTransactionState.ConfirmFailed); break; case TccTransactionState.Cancelling: foreach (var a in _works) { if (a.WorkState != TccWorkState.Cancelled && a.WorkState != TccWorkState.None) { rc.AddWork(a, TccAction.Cancel); } } nextState = _lock != null ? TccTransactionState.LockCanceling :TccTransactionState.Cancelled; rc.SetNextState(nextState, TccTransactionState.CancelFailed); break; case TccTransactionState.LockCanceling: rc.AddWork(_lock, TccAction.Cancel); rc.SetNextState(TccTransactionState.Cancelled, TccTransactionState.CancelFailed); break; } return(rc); }