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); }
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); }
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(); } }