コード例 #1
0
        public async Task <long?> DeductBalance(DeductBalanceInput input, TccMethodType tccMethodType)
        {
            var account = await GetAccountById(input.AccountId);

            var trans = await _repository.BeginTransactionAsync();

            BalanceRecord balanceRecord = null;

            switch (tccMethodType)
            {
            case TccMethodType.Try:
                account.Balance     -= input.OrderBalance;
                account.LockBalance += input.OrderBalance;
                balanceRecord        = new BalanceRecord()
                {
                    OrderBalance = input.OrderBalance,
                    OrderId      = input.OrderId,
                    PayStatus    = PayStatus.NoPay
                };
                await _repository.InsertAsync(balanceRecord);

                RpcContext.GetContext().SetAttachment("balanceRecordId", balanceRecord.Id);
                break;

            case TccMethodType.Confirm:
                account.LockBalance -= input.OrderBalance;
                var balanceRecordId1 = RpcContext.GetContext().GetAttachment("orderBalanceId")?.To <long>();
                if (balanceRecordId1.HasValue)
                {
                    balanceRecord = await _repository.GetByIdAsync <BalanceRecord>(balanceRecordId1.Value);

                    balanceRecord.PayStatus = PayStatus.Payed;
                    await _repository.UpdateAsync(balanceRecord);
                }
                break;

            case TccMethodType.Cancel:
                account.Balance     += input.OrderBalance;
                account.LockBalance -= input.OrderBalance;
                var balanceRecordId2 = RpcContext.GetContext().GetAttachment("orderBalanceId")?.To <long>();
                if (balanceRecordId2.HasValue)
                {
                    balanceRecord = await _repository.GetByIdAsync <BalanceRecord>(balanceRecordId2.Value);

                    balanceRecord.PayStatus = PayStatus.Cancel;
                    await _repository.UpdateAsync(balanceRecord);
                }
                break;
            }


            await _repository.UpdateAsync(account);

            await trans.CommitAsync();

            await _accountCache.RemoveAsync($"Account:Name:{account.Name}");

            return(balanceRecord?.Id);
        }
コード例 #2
0
        public static (ObjectMethodExecutor, bool, object) GetTccExcutorInfo([NotNull] this ServiceEntry serviceEntry,
                                                                             string serviceKey, TccMethodType tccMethodType)
        {
            Check.NotNull(serviceEntry, nameof(serviceEntry));
            Debug.Assert(serviceEntry.IsLocal);
            var instance =
                EngineContext.Current.ResolveServiceEntryInstance(serviceKey, serviceEntry.ServiceType);
            var methods = instance.GetType().GetTypeInfo().GetMethods();
            var implementationMethod = methods.Single(p => p.AchievingEquality(serviceEntry.MethodInfo));

            if (tccMethodType == TccMethodType.Try)
            {
                return(implementationMethod.CreateExecutor(instance.GetType()),
                       implementationMethod.IsAsyncMethodInfo(), instance);
            }

            var tccTransactionProvider =
                implementationMethod.GetCustomAttributes().OfType <ITccTransactionProvider>().First();
            MethodInfo execMethod;

            if (tccMethodType == TccMethodType.Confirm)
            {
                execMethod = GetCompareMethod(methods, implementationMethod, tccTransactionProvider.ConfirmMethod);
            }
            else
            {
                execMethod = GetCompareMethod(methods, implementationMethod, tccTransactionProvider.CancelMethod);
            }

            if (execMethod == null)
            {
                throw new LmsException($"未定义{tccMethodType}方法");
            }

            return(execMethod.CreateExecutor(instance.GetType()), implementationMethod.IsAsyncMethodInfo(),
                   instance);
        }
コード例 #3
0
        public static async Task ExcuteTccMethod(this ILmsMethodInvocation invocation, TccMethodType tccMethodType)
        {
            var serviceEntry = invocation.ArgumentsDictionary["serviceEntry"] as ServiceEntry;

            Debug.Assert(serviceEntry != null);
            var serviceKey = invocation.ArgumentsDictionary["serviceKey"] as string;
            var parameters = invocation.ArgumentsDictionary["parameters"] as object[];

            if (serviceEntry.IsLocal)
            {
                var excutorInfo = serviceEntry.GetTccExcutorInfo(serviceKey, tccMethodType);
                if (excutorInfo.Item2)
                {
                    invocation.ReturnValue = await excutorInfo.Item1.ExecuteAsync(excutorInfo.Item3, parameters);
                }
                else
                {
                    invocation.ReturnValue = excutorInfo.Item1.Execute(excutorInfo.Item3, parameters);
                }
            }
            else
            {
                await invocation.ProceedAsync();
            }
        }