我正在寻找一种在 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
方法,我宁愿只在一个地方处理这个问题。