WCF可靠性问题
尝试测试我的 wcf 服务的可靠性。我正在从客户端循环内调用 wcf 服务。 WCF REST服务(WebhttpBinding)进行一些数据处理并插入 记录到数据库中。整个操作是在事务内完成的。
我发现,如果我将 InstanceContextMode 设置为 PerCall,则在大约 60 条消息(从循环内部调用服务的 60 倍)中,只有 40 条消息会传递到数据库。没有错误,没有例外。这些消息刚刚被丢弃。
如果我将 InstanceContextMode 设置为 Single,那么我会看到所有消息都到达数据库。 InstanceContextMode.Percall 有损是预期的行为吗?另外,我没有设置并发。任何澄清都会非常有帮助。添加了代码。使用 MySQL 作为数据库...
编辑我的坏处 - 我刚刚注意到我在服务器端遇到异常 - {“尝试获取锁定时发现死锁;尝试重新启动事务”}
这是因为当事务正在进行时,同一记录上调用了另一个事务。如果事务失败一次,可以通过重新启动事务来修复它。
服务
[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;
}
}
客户端只是循环调用服务
Trying to test the reliability of my wcf services. I am calling a wcf service within a loop from the client side. The wcf rest service (webhttpbinding) does some data processing and inserts
records into a database. The entire operation is done within a transaction.
I find that out of about 60 messages (60 times the service being called from inside a loop) only 40 are going through to the db if I set my InstanceContextMode to PerCall. There are no errors no exceptions. The messages are just being dropped.
If I set the InstanceContextMode to Single then I see all messages getting to the db.
Is the InstanceContextMode.Percall being lossy the expected behavior? Also, I do not have concurrency set. Any clarifications would be greatly helpful. Added the code. Using MySQL as the db...
EDIT My bad - I just noticed that I get an exception on the server side - {"Deadlock found when trying to get lock; try restarting transaction"}
This is because there is another transaction invoked on the same records while a transaction is under progress. Fixing it by restarting the transaction if it fails once.
The service
[WebInvoke(UriTemplate = "employee", Method = "POST")]
public long AddNewEmployee(EmployeeEntity newEmployee)
{
EmployeeRepository eRep = new EmployeeRepository();
return eRep.AddNewEmployee(newEventEntity);
}
The repository class constructor initializes the object context
public EmployeeRepository()
{
bd = new EmployeeEntity();
}
Code - The service call
//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;
}
}
The client side just calls the service in a loop
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我强烈建议为任何 WCF 添加全局异常处理。它帮助我节省了许多时间的调试时间,并且可以捕获任何未处理的异常。它比 ASP.NET 中的 global.ascx 涉及更多一点
步骤 1 - 实现 IErroHander 和 IServiceBehavior
请注意,在 HandleError 中我正在使用 Enterprise Library 来处理异常。您也可以在此处使用您的自定义实现。
第 2 步 - 创建错误元素
第 3 步 - 将元素添加到 web.config
I highly suggest adding global exception handling for any WCF. It has helped me save many hours of debugging and will catch any unhandled exceptions. It's a little bit more involved than global.ascx in ASP.NET
Step 1 - Implement IErroHander and IServiceBehavior
Notice inside HandleError I'm using Enterprise Library to handle the exception. You can use your custom implementation here as well.
Step 2 - Create Error Element
Step 3 - Add Element to web.config