Пример #1
0
        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);
        }
Пример #2
0
        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());
                    }
                }
            }
        }
Пример #3
0
        /// <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);
        }