具有多个记录的实体框架乐观并发异常已更新

时间:2018-07-19 13:38:28

标签: entity-framework

当通过实体框架数据库上下文更新数据库中的多个记录时,一个记录将引发乐观并发异常,并且该记录不会在数据库中更新。但是我发现其他更新的记录都保留在数据库中。乐观并发异常是否不应该回滚在乐观并发异常之前进行的所有更改?

1 个答案:

答案 0 :(得分:0)

我敢肯定,每当需要更新时,EF库都会引发异常,但是SQL Server响应表明没有任何异常。

  

当预期实体的SaveChanges将导致数据库更新,但实际上数据库中没有行受到影响时,DbContext引发异常。这通常表明数据库已被并发更新,因此预期匹配的并发令牌实际上并未匹配。请注意,出于安全考虑,此异常引用的状态条目未进行序列化,并且序列化后对状态条目的访问将返回null。

此外,实体框架还可以将每个对象转换为单个SQL UPDATE语句,例如

exec sp_executesql N'SET NOCOUNT ON;

UPDATE [Students] SET [Name] = @p0
WHERE [StudentId] = @p1;
SELECT @@ROWCOUNT;

UPDATE [Students] SET [Name] = @p2
WHERE [StudentId] = @p3;
SELECT @@ROWCOUNT;

UPDATE [Students] SET [Name] = @p4
WHERE [StudentId] = @p5;
SELECT @@ROWCOUNT;

',N'@p1 int,@p0 nvarchar(4000),@p3 int,@p2 nvarchar(4000),@p5 int,@p4 
nvarchar(4000)',
@p1=1,@p0=N'Bill',@p3=2,@p2=N'Steve',@p5=3,@p4=N'James'

go

这意味着SQL Server一切正常,而事务由Entity Framework提交。只有EF会引发异常,以使您知道出了点问题。在您的情况下,这些语句之一不进行任何更新,更新的行数为0。

如果需要在更新期间回滚所有更改,则必须将其封装在另一个事务中。根据需要提交并回滚。

using (var dbContextTransaction = context.Database.BeginTransaction()) 
{ 
   try 
   { 
      // Do your stuff

      context.SaveChanges(); 

      dbContextTransaction.Commit(); 
   } 
   catch (DbUpdateConcurrencyException) 
   { 
      // Expected
      dbContextTransaction.Rollback(); 
   }
   catch (Exception)
   {
      // Unexpected
      dbContextTransaction.Rollback();
   }
}

相关阅读:

有关DbUpdateConcurrencyException Class

的更多信息

有关Update Data in Disconnected Scenario in Entity Framework Core(更新多个实体)的更多信息

有关Entity Framework Working with Transactions

的更多信息