提问人:Masoud 提问时间:11/1/2023 最后编辑:Masoud 更新时间:11/14/2023 访问量:72
在事务中调用 WCF 方法会导致错误
Calling WCF method inside a Transaction cause error
问:
我有一个复杂的应用程序,遇到了一个错误。我用下面的代码简化了我的实际问题。
我有一个 WCF 服务,其中包含对我的一个表执行 select 的方法:
public string FindDocumentNumber(int documentId)
{
using(var context = new MyDbContext())
{
return context.Documents.Where(x=>x.Id == documentId && x.Tag == "*")
.Select(x=>x.Number).FirstOrDefault();
}
}
在我的控制台应用程序中,我有以下代码:
using(var scope = new TransactionScope())
{
using(var context = new MyDbContext())
{
var doc = context.Documents.Where(x=>x.Id == 12345).FirstOrDefault();
doc.Tag = "*";
context.SaveChange();
}
...
var number = myWCFService.FindDocumentNumber(12345); // At this point, I encounter an error
...
//some other updates on document with Id = 12345
scope.Complete();
}
但是,在运行代码时,我遇到以下错误:
System.Data.Entity.Core.EntityCommandExecutionException
HResult=0x8013193C Message=执行 命令定义。有关详细信息,请参阅内部异常。
源 = StackTrace:内部异常 1:SqlException:执行超时已过期。这 在完成操作或 服务器没有响应。
内部异常 2:Win32Exception:等待操作超时
问题出在哪里?
答:
问题在于,您正在尝试在事务范围内释放 DbContext。Tx 作用域将希望确保同时提交对 DbContext 的更改以及识别它的任何其他更改,这将阻止 .在它的块的末尾,这很可能是异常的来源。DbContext
Dispose
using
如果 API 调用设置为在 Tx 范围内工作(我怀疑它不是),那么您需要反转您的块以避免该错误:using
using(var context = new MyDbContext())
{
using(var scope = new TransactionScope())
{
var doc = context.Documents.Where(x=>x.Id == 12345).Single();
doc.Tag = "*";
context.SaveChange();
...
var number = myWCFService.FindDocumentNumber(12345); // At this point, I encounter an error
...
//some other updates on document with Id = 12345
scope.Complete();
}
}
然而,正如评论所说,Tx Scope 甚至可能没有必要。DbContext 包装自己的事务,因此,如果存在您不想将更改提交到数据库的情况,请避免调用 'SaveChanges,直到您满意应该提交所有内容。
using(var context = new MyDbContext())
{
var doc = context.Documents.Where(x=>x.Id == 12345).Single();
doc.Tag = "*";
...
var number = myWCFService.FindDocumentNumber(12345); // At this point, I encounter an error
...
//some other updates on document with Id = 12345
if (everythingIsOk) // Use a flag, check state, whatever....
context.SaveChanges();
}
事务范围旨在协调多个单独的操作,以确保它们一起提交或回滚。我看到使用单独事务的一个常见场景是,当开发人员认为他们需要先保存记录时,例如获取生成的 ID,以便他们可以在其他地方使用或设置该 ID,但随后仍然希望选择“退出”该插入。在极少数情况下,这可能是一个合理的问题,但通常情况下,它只是一个有限的实现,有更好的选择可以考虑。
下一个:WCF 异步操作超时
评论
SaveChanges
TransactionScope
SaveChanges
TransactionScope
SaveChanges