简体   繁体   English

实体框架如何在不使用timestmp或rowversion的情况下检测并发冲突

[英]How will entity framework detect concurrency conflicts , without using timestmp or rowversion

I am working on an asp.net mvc web application that uses entity framework . 我正在使用实体框架的asp.net mvc Web应用程序上工作。 I have the following model class inside my asp.net mvc web application:- 我的asp.net mvc Web应用程序中有以下模型类:

public partial class TMSSwitchPort
{
    public int TechnologyID { get; set; }
    public int SwitchID { get; set; }
    public string PortNumber { get; set; }

    public virtual Technology Technology { get; set; }
    public virtual TMSSwitch TMSSwitch { get; set; }
}

And I have the following repository method:- 我有以下存储库方法:

public void changeDeviceSwitch(int fromID , int toID)
{

    var currentdevices = tms.TMSSwitchPorts.Where(a => a.SwitchID == fromID);
    foreach (var d in currentdevices)
    {
        tms.TMSSwitchPorts.Remove(d);            
    }
    foreach (var d in currentdevices)
    {
        TMSSwitchPort tsp = new TMSSwitchPort() { SwitchID = toID,
            TechnologyID = d.TechnologyID, PortNumber = d.PortNumber };
        tms.TMSSwitchPorts.Add(d);
    }
    tms.SaveChanges();
}

The above method will mainly retrieve all objects that have specific switchID , delete them, and add new records with new switchID. 上面的方法将主要检索具有特定switchID的所有对象,删除它们,并使用新的switchID添加新记录。 Currently I am trying to understand what will happen when concurrent users execute the method at the same time. 当前,我正在尝试了解并发用户同时执行该方法时会发生什么。 From my test I find that the first user will be able to delete and add new records, while the other users will get DbUpdateConcurrencyException. 从我的测试中,我发现第一个用户将能够删除和添加新记录,而其他用户将获得DbUpdateConcurrencyException。 So from my understanding I observe the following scenario, let say UserA & UserB access the same method at the same time:- 因此,根据我的理解,我观察到以下情况,假设UserA和UserB同时访问相同的方法:

  • UserA retrieve all the currentdevices. UserA检索所有当前设备。

  • UserB retrieve all the currentdevices at the same time. UserB同时检索所有当前设备。

  • UserA mark all objects for deletion, create new objects, Save(). UserA将所有对象标记为删除,创建新对象Save()。

  • UserB mark all objects for deletion, create new objects, UserB将所有对象标记为删除,创建新对象,

  • Now when userB reaches the Save() , EF will find that there are some objects (or all of them) that have been marked for deletion but no longer exists (because they were deleted by UserA), and it will raise the DbUpdateConcurrencyException. 现在,当userB到达Save()时,EF将发现有些对象(或所有对象)已被标记为删除,但不再存在(因为它们已被UserA删除),这将引发DbUpdateConcurrencyException。

So this mean that EF will raise DbUpdateConcurrencyException, when it tries to delete an object/s that no longer exists , even if I am not using a timestamp . 因此,这意味着EF在尝试删除不再存在的对象时将引发DbUpdateConcurrencyException,即使我没有使用时间戳也是如此。 I check the sql profiler and the generated sql statement for the delete operation looks as follow:- 我检查sql探查器,并为删除操作生成了sql语句,如下所示:

exec sp_executesql N'delete [dbo].[TMSSwitchPorts]
where (([SwitchID] = @0) and ([PortNumber] = @1))',N'@0 int,@1 nvarchar(10)',@0=467,@1=N'a'

So is my understanding to the way EF will react to the above code is correct ? 那么我对EF对上述代码的反应方式的理解是正确的吗?

If you read the MSDN article for DbUpdateConcurrencyException you can see these notes that explain it: 如果您阅读有关DbUpdateConcurrencyException的MSDN文章, DbUpdateConcurrencyException可以看到以下说明来对其进行解释:

Exception thrown by DbContext when it was expected that SaveChanges for an entity would result in a database update but in fact no rows in the database were affected. 当预期实体的SaveChanges将导致数据库更新,但实际上数据库中没有行受到影响时,DbContext引发异常。 This usually indicates that the database has been concurrently updated such that a concurrency token that was expected to match did not actually match. 这通常表明数据库已被并发更新,因此预期匹配的并发令牌实际上并未匹配。 Note that state entries referenced by this exception are not serialized due to security and accesses to the state entries after serialization will return null. 请注意,由于安全原因,此异常引用的状态条目不会被序列化,序列化后对状态条目的访问将返回null。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM