public bool Commit(string tranId) { for (int i = 0; i < List.Count; i++) { var delegateItem = List[i]; if (delegateItem != null && delegateItem.TransactionId == tranId) { try { lock (delegateItem) { if (delegateItem.Handled) { return(false); } if (delegateItem.CommitAction != null) { delegateItem.CommitAction(); if (delegateItem.RetryCommitFilePath != null) { _faildCommitBuilder.CommitSuccess(delegateItem.RetryCommitFilePath); delegateItem.RetryCommitFilePath = null; } _loggerTran?.LogInformation("事务{0}提交完毕,请求数据:{1}", delegateItem.TransactionId, delegateItem.RequestCommand.ToJsonString()); } delegateItem.Handled = true; } } catch (Exception ex) { _logger?.LogError(ex, ex.Message); throw ex; } finally { lock (List) { List.Remove(delegateItem); } } return(true); } } return(false); }
public void Handle(NetClient netclient, InvokeCommand cmd) { TransactionDelegate transactionDelegate = null; MicroServiceControllerBase controller = null; object[] parameters = null; try { MicroServiceControllerBase.RequestingCommand.Value = cmd; var controllerTypeInfo = _MicroServiceProvider.ServiceNames[cmd.Service]; object userContent = null; if (controllerTypeInfo.NeedAuthorize) { var auth = _MicroServiceProvider.ServiceProvider.GetService <IAuthenticationHandler>(); if (auth != null) { userContent = auth.Authenticate(cmd.Header); } } controller = (MicroServiceControllerBase)_MicroServiceProvider.ServiceProvider.GetService(controllerTypeInfo.Type); controller.UserContent = userContent; controller.NetClient = netclient; controller._keyLocker = _MicroServiceProvider.ServiceProvider.GetService <IKeyLocker>(); if (_logger != null && _logger.IsEnabled(LogLevel.Trace)) { var str = string.Format("invoke service:{0} method:{1} parameters:{2}", cmd.Service, cmd.Method, cmd.Parameters.ToJsonString()); if (str != LastInvokingMsgString || (DateTime.Now - LastInvokingMsgStringTime).TotalSeconds > 5) { LastInvokingMsgStringTime = DateTime.Now; LastInvokingMsgString = str; _logger?.LogTrace(str); } } var methodInfo = controllerTypeInfo.Methods.FirstOrDefault(m => m.Method.Name == cmd.Method); if (methodInfo == null) { throw new Exception($"{cmd.Service}没有提供{cmd.Method}方法"); } if (methodInfo.NeedAuthorize && userContent == null) { var auth = _MicroServiceProvider.ServiceProvider.GetService <IAuthenticationHandler>(); if (auth != null) { userContent = auth.Authenticate(cmd.Header); } } MicroServiceControllerBase.Current = controller; var parameterInfos = methodInfo.Method.GetParameters(); object result = null; int startPIndex = 0; if (parameterInfos.Length > 0) { parameters = new object[parameterInfos.Length]; if (parameterInfos[0].ParameterType == typeof(TransactionDelegate)) { startPIndex = 1; parameters[0] = transactionDelegate = new TransactionDelegate(cmd.Header["TranId"]); transactionDelegate.RequestCommand = cmd; } } controller.OnBeforeAction(cmd.Method, parameters); if (parameterInfos.Length > 0) { for (int i = startPIndex, index = 0; i < parameters.Length && index < cmd.Parameters.Length; i++, index++) { string pvalue = cmd.Parameters[index]; if (pvalue == null) { continue; } try { parameters[i] = Newtonsoft.Json.JsonConvert.DeserializeObject(pvalue, parameterInfos[i].ParameterType); } catch (Exception) { _logger?.LogError("转换参数出错,name:{0} cmd:{1}", parameterInfos[i].Name, cmd.ToJsonString()); } } } result = methodInfo.Method.Invoke(controller, parameters); controller.OnAfterAction(cmd.Method, parameters); var supportTran = false; if (transactionDelegate != null && (transactionDelegate.CommitAction != null || transactionDelegate.RollbackAction != null)) { supportTran = true; } else if (controller.TransactionControl != null && (controller.TransactionControl.CommitAction != null || controller.TransactionControl.RollbackAction != null)) { transactionDelegate = controller.TransactionControl; transactionDelegate.RequestCommand = cmd; supportTran = true; } if (supportTran && cmd.Header.ContainsKey("Tran") && cmd.Header["Tran"] == "0") { //调用端不需要事务支持 supportTran = false; } var resultdata = Encoding.UTF8.GetBytes(new InvokeResult { Success = true, SupportTransaction = supportTran, Data = result }.ToJsonString()); if (!supportTran && transactionDelegate != null) { //不需要事务支持,提交现有事务 if (transactionDelegate.CommitAction != null) { transactionDelegate.CommitAction(); } transactionDelegate = null; } netclient.WriteServiceData(resultdata); if (!supportTran) { return; } netclient.ReadTimeout = 0; while (true) { cmd = netclient.ReadServiceObject <InvokeCommand>(); if (cmd.Type == InvokeType.CommitTranaction) { var tran = transactionDelegate; transactionDelegate = null; if (tran != null && tran.CommitAction != null) { try { tran.CommitAction(); if (tran.RetryCommitFilePath != null) { _faildCommitBuilder.CommitSuccess(tran.RetryCommitFilePath); tran.RetryCommitFilePath = null; } } catch (Exception ex) { if (tran.RetryCommitFilePath != null) { _faildCommitBuilder.CommitFaild(tran.RetryCommitFilePath); tran.RetryCommitFilePath = null; } _loggerTran?.LogInformation("事务{0}提交失败,{1}", tran.TransactionId, ex.Message); transactionDelegate = null; throw ex; } _loggerTran?.LogInformation("事务{0}提交完毕", tran.TransactionId); } netclient.WriteServiceData(new InvokeResult() { Success = true }); return; } else if (cmd.Type == InvokeType.RollbackTranaction) { var tran = transactionDelegate; transactionDelegate = null; if (tran != null && tran.RollbackAction != null) { tran.RollbackAction(); if (tran.RetryCommitFilePath != null) { _faildCommitBuilder.Rollback(tran.RetryCommitFilePath); tran.RetryCommitFilePath = null; } _loggerTran?.LogInformation("事务{0}回滚完毕,请求数据:{1}", tran.TransactionId, tran.RequestCommand.ToJsonString()); } netclient.WriteServiceData(new InvokeResult() { Success = true }); return; } else if (cmd.Type == InvokeType.HealthyCheck) { var tran = transactionDelegate; if (tran.CommitAction != null) { tran.RetryCommitFilePath = _faildCommitBuilder.Build(tran.TransactionId, tran.RequestCommand, controller.UserContent); } _loggerTran?.LogInformation("准备提交事务{0},请求数据:{1},身份验证信息:{2}", tran.TransactionId, tran.RequestCommand.ToJsonString(), controller.UserContent); netclient.WriteServiceData(new InvokeResult { Success = transactionDelegate.AgreeCommit }); } } } catch (SocketException) { if (transactionDelegate != null) { //连接意外中断,交给TransactionDelegateCenter事后处理 _logger?.LogInformation("连接意外中断,交给TransactionDelegateCenter事后处理,事务id:{0}", transactionDelegate.TransactionId); _transactionDelegateCenter.AddTransactionDelegate(transactionDelegate); transactionDelegate = null; } return; } catch (ResponseEndException) { return; } catch (Exception ex) { if (ex is TargetInvocationException && ex.InnerException != null) { ex = ex.InnerException; } if (transactionDelegate != null) { try { if (transactionDelegate.RollbackAction != null) { transactionDelegate.RollbackAction(); _loggerTran?.LogInformation("事务{0}回滚完毕,请求数据:{1}", transactionDelegate.TransactionId, transactionDelegate.RequestCommand.ToJsonString()); } } catch (Exception rollex) { _logger?.LogError(rollex, rollex.Message); } transactionDelegate = null; } try { if (controller?.OnInvokeError(cmd.Method, parameters, ex) == false) { _logger?.LogError(ex, ex.Message); } } catch (ResponseEndException) { return; } while (ex.InnerException != null) { ex = ex.InnerException; } netclient.WriteServiceData(new InvokeResult { Success = false, Error = ex.Message }); return; } finally { MicroServiceControllerBase.Current = null; controller?.OnUnLoad(); } }