public ErrorCode ChangeBalance(string transactionid, decimal amount) { if (_from.GetBalance() < amount) { return(ErrorCode.NotEnoughtBalance); } var fromTransactionResult = _from.DecreaseBalance(amount, transactionid); if (fromTransactionResult != ErrorCode.Success) { return(fromTransactionResult); } var toTransactionResult = _to.IncreaseBalance(amount, transactionid); if (toTransactionResult != ErrorCode.Success) { _from.Rollback(transactionid); } return(toTransactionResult); }
protected virtual void TryRollback(IBalanceManager balanceManager, string balanceName, string transactionId) { var checkErroCode = balanceManager.CheckTransaction(transactionId); if (checkErroCode == ErrorCode.Success) { var rollbackErrorCode = balanceManager.Rollback(transactionId); if (rollbackErrorCode == ErrorCode.Success) { Exception.LogRollbackSuccess(balanceName); } else { if (rollbackErrorCode == ErrorCode.UnknownError && TransactionRollbacked(balanceManager, transactionId)) { Exception.LogRollbackSuccess(balanceName); } else { Exception.LogRollbackFailure(balanceName, rollbackErrorCode.ToString()); } } } }
/// <summary> /// Rollbacks transaction for specified balance type /// </summary> /// <param name="transactionId">Transactino ID</param> /// <param name="type">balance type (rollbacks both sides if null)</param> /// <returns></returns> private async Task <(bool success, ErrorCode error)> RollbackTransaction(string transactionId, BalanceFactoryType?type = null) { Task casTask = default; Task balTask = default; Action <ErrorCode> RepeatRollback = (ErrorCode err) => { while (err != ErrorCode.TransactionAlreadyMarkedAsRollback) { err = _casinoManager.Rollback(transactionId); } }; if (type == null) { var casResult = _casinoManager.Rollback(transactionId); var balResult = _gameManager.Rollback(transactionId); if (casResult != ErrorCode.Success) { casTask = Task.Run(() => RepeatRollback(casResult)); } if (balResult != ErrorCode.Success) { balTask = Task.Run(() => RepeatRollback(balResult)); } } else { ErrorCode res; switch (type) { case BalanceFactoryType.Game: res = _gameManager.Rollback(transactionId); if (res != ErrorCode.Success) { balTask = Task.Run(() => RepeatRollback(res)); } break; case BalanceFactoryType.Casino: res = _casinoManager.Rollback(transactionId); if (res != ErrorCode.Success) { //casTask = Task.Run(() => //{ // while (res != ErrorCode.TransactionAlreadyMarkedAsRollback) // { // res = _casinoManager.Rollback(transactionId); // } //}); casTask = Task.Run(() => RepeatRollback(res)); } break; default: throw new ArgumentException(); } } if (casTask?.Status == TaskStatus.Running) { await casTask.ConfigureAwait(false); } if (balTask?.Status == TaskStatus.Running) { await balTask.ConfigureAwait(false); } return(success : true, error : ErrorCode.Success); }