【发布时间】:2013-08-17 21:42:10
【问题描述】:
我正在寻找一种在 TransactionScope 处于活动状态时执行查询的方法,并忽略 TransactionScope - 基本上,无论如何我都想执行这个特定的查询。
我使用 EF 代码优先,以及应用程序的设计方式,在一次调用中多次打开新的数据上下文,每次都有自己的更改,所有这些都包含在单个 TransactionScope 中,假设没有失败,最后调用了Complete()。在上下文中,我们覆盖了SaveChanges,因此如果base.SaveChanges() 发生任何异常,我们可以在回滚事务之前捕获它并记录到数据库。
由于SaveChanges 发生在事务内部,因此显然不会发生日志记录,因为它与原始调用属于同一事务。我试图完全忽略 TransactionScope,只是为了记录代码。
这是一些精简的代码:
// From the context
public override int SaveChanges() {
try {
return base.SaveChanges();
} catch (Exception ex) {
// Writes to the log table - I want this to run no matter what
LogRepo.Log(/*stuff to log from the context*/);
throw;
}
}
// Inside the business logic
public void DoSomething() {
try {
using (var scope = new TransactionScope()) {
using (var context = new FooContext()) {
// Do something
context.SaveChanges();
}
using (var context = new FooContext()) {
// Do something else
context.SaveChanges();
}
scope.Complete();
}
} catch (Exception ex) {
// scope.Complete is never called, so the transaction is rolled back
}
}
我尝试使用常规 ADO.NET 而不是 EF 进行日志记录,但结果仍然相同 - 它也会回滚。
我需要在SaveChanges 内部进行错误处理,因为我正在记录的是正在保存的实体的状态 - 所以我不能轻易地将记录移动到其他地方。我可以在SaveChanges catch 中构建消息,然后将其抛出并让DoSomething catch 记录它,但是DoSomething 方法有很多,我宁愿只在一个地方处理。
【问题讨论】:
标签: c# entity-framework transactions entity-framework-5 transactionscope