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