【发布时间】:2018-02-15 00:47:55
【问题描述】:
我需要在 EF 中事务回滚后写入日志表。 当前代码:
using (MyDataBase db = new DataBase())
{
using (var dbContextTransaction = db.Database.BeginTransaction())
{
try
{
//Inserting several records to different tables
var newEntity = new Entity();
...
db.Entity.Add(newEntity);
db.SaveChanges();
db.up_StoredProcCall;
dbContextTransaction.Commit();
}
catch (Exception ex)
{
dbContextTransaction.Rollback();
var logEntry = new LogEntry();
...
db.LogEntry.Add(logEntry);
db.SaveChanges();
}
}
}
它不起作用,因为 EF 会在内部缓存所有插入并将它们全部与单个事务中的日志记录一起刷新:
db.LogEntry.Add(logEntry);
db.SaveChanges();
实现目标的最佳方式是什么:
【问题讨论】:
-
在 SQL 服务器端,如果一个事务回滚,它通常是注定的(不是比喻,这是它的技术术语),这意味着不能执行更多的数据修改语句,包括任何写入到日志表。因此,您必须至少需要一个单独的事务来记录故障。
-
我不熟悉 EF 如何处理事务,确切地说。如果它对
dbContextTransaction仍然存在感到不安,请将异常存储在来自catch的局部变量中,然后检查它并在using之外登录。 -
EF 中的事务仅更改 SQL 端更改的事务上下文。通常,它会将在 SaveChanges 调用之前所做的所有更改包装在一个事务中。事务上下文对此进行了更改,例如将存储过程的调用包含在事务中。但它对 ChangeTracker 没有任何作用。因此,将日志表插入远离事务范围将无济于事,因为事务中所做的所有更改都将保留在 EF 的缓存 (ChangeTracker) 中,并将转到 SaveChanges 上的数据库。只有将日志表插入移动到另一个 DbContext 才会有所帮助。但可能有更方便的解决方案?
-
“在 SQL Server 端,如果事务回滚......意味着不能执行更多的数据修改语句” - 这是不正确的。回滚只会丢弃事务中所做的所有更改。但回滚后,您可以写入数据库。
-
哎呀。你是对的,我把它与 errors 混淆了,它使事务 before 回滚。并非所有错误都会导致事务终止(也不是所有错误都会导致事务终止)。在明确的
ROLLBACK之后,事务不再存在,所以忘记这一切。
标签: c# .net sql-server entity-framework transactions