简体   繁体   中英

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 . I have the following model class inside my asp.net mvc web application:-

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. 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. So from my understanding I observe the following scenario, let say UserA & UserB access the same method at the same time:-

  • UserA retrieve all the currentdevices.

  • UserB retrieve all the currentdevices at the same time.

  • UserA mark all objects for deletion, create new objects, Save().

  • UserB mark all objects for deletion, create new objects,

  • 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.

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 . I check the sql profiler and the generated sql statement for the delete operation looks as follow:-

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 ?

If you read the MSDN article for DbUpdateConcurrencyException you can see these notes that explain it:

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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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