WCF 可靠性问题
Posted
技术标签:
【中文标题】WCF 可靠性问题【英文标题】:WCF reliability issues 【发布时间】:2011-07-27 22:19:33 【问题描述】:试图测试我的 wcf 服务的可靠性。我正在从客户端循环调用 wcf 服务。 wcf 休息服务(webhttpbinding)做一些数据处理和插入 记录到数据库中。整个操作在一个事务中完成。
如果我将 InstanceContextMode 设置为 PerCall,我发现在大约 60 条消息(从循环内调用服务的 60 倍)中只有 40 条消息通过数据库。没有错误没有例外。消息刚刚被丢弃。
如果我将 InstanceContextMode 设置为 Single,那么我会看到所有消息都到达了 db。 InstanceContextMode.Percall 是有损的预期行为吗?另外,我没有设置并发。任何澄清都会非常有帮助。添加了代码。使用 mysql 作为数据库...
编辑我的错 - 我刚刚注意到服务器端出现异常 - "Deadlock found when trying to get lock; try restarting transaction"
这是因为在进行事务时,对同一记录调用了另一个事务。如果它失败一次,则通过重新启动事务来修复它。
服务
[WebInvoke(UriTemplate = "employee", Method = "POST")]
public long AddNewEmployee(EmployeeEntity newEmployee)
EmployeeRepository eRep = new EmployeeRepository();
return eRep.AddNewEmployee(newEventEntity);
存储库类构造函数初始化对象上下文
public EmployeeRepository()
bd = new EmployeeEntity();
代码 - 服务调用
//bd is the object context
//there are two tables
internal long AddNewEmployee(EmployeeEntity newEmployee)
bool tSuccess = false;
using (TransactionScope transaction = new TransactionScope())
try
//get existing employees
var existingEmployees = from employee
in bd.employees select employee;
List<employee> returnedEmployees = new List<employee>();
//Do some processing
returnedEmployees = DoSomeprocessing(existingEmployees);
//Insert returned employees as updates
foreach (employee e in returnedEmployees)
bd.employees.AddObject(e);
bd.SaveChanges();
returnedEmployees.Clear();
//add to second table
bd.otherdetails.AddObject(newEmployee);
bd.SaveChanges();
//Transaction Complete
transaction.Complete();
tSuccess = true;
catch (Exception e)
//return something meaningful
return -1;
if (tSuccess)
//End Transaction
bd.AcceptAllChanges();
return 200;
else
return -1;
客户端只是循环调用服务
【问题讨论】:
当你说“没有错误没有例外”时,你的意思是什么?客户端没有看到任何错误? WCF 异常处理程序没有触发?服务方法本身没有异常? 客户端没有看到任何错误。服务器方法也不会抛出异常。对服务的一些调用刚刚被丢弃。当我使用 instancecontext 单一模式时,一切正常.. 【参考方案1】:我强烈建议为任何 WCF 添加全局异常处理。它帮助我节省了许多小时的调试时间,并且可以捕获任何未处理的异常。它比 ASP.NET 中的 global.ascx 涉及更多一点
第 1 步 - 实施 IerroHander 和 IServiceBehavior
注意 HandleError 内部我正在使用 Enterprise Library 来处理异常。您也可以在此处使用您的自定义实现。
public class ErrorHandler : IErrorHandler, IServiceBehavior
public bool HandleError(Exception error)
// Returning true indicates you performed your behavior.
return true;
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
// Log Exception
ExceptionPolicy.HandleException(error, "ExceptionPolicy");
// Shield the unknown exception
FaultException faultException = new FaultException(
"Server error encountered. All details have been logged.");
MessageFault messageFault = faultException.CreateMessageFault();
fault = Message.CreateMessage(version, messageFault, faultException.Action);
private IErrorHandler errorHandler = null;
public ErrorHandler()
public ErrorHandler(IErrorHandler errorHandler)
this.errorHandler = errorHandler;
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
ChannelDispatcher cd = cdb as ChannelDispatcher;
if (cd != null)
cd.ErrorHandlers.Add(new ErrorHandler());
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
ChannelDispatcher cd = cdb as ChannelDispatcher;
if (cd != null)
cd.ErrorHandlers.Add(new ErrorHandler());
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
第 2 步 - 创建错误元素
public class ErrorHandlerElement : BehaviorExtensionElement
protected override object CreateBehavior()
return new ErrorHandler();
public override Type BehaviorType
get
return typeof(ErrorHandler);
第 3 步 - 将元素添加到 web.config
<serviceBehaviors>
<behavior>
<ErrorHandler />
</behavior>
</serviceBehaviors>
【讨论】:
使用ExceptionPolicy.HandleException
记录日志?以上是关于WCF 可靠性问题的主要内容,如果未能解决你的问题,请参考以下文章
启用可靠会话时 WCF ContractFilter 不匹配
在同一 Service Fabric 可靠服务中同时使用 WCF 服务和 Web Api