Jasinski Technical Wiki

Navigation

Home Page
Index
All Pages

Quick Search
»
Advanced Search »

Contributor Links

Create a new Page
Administration
File Management
Login/Logout
Your Profile

Other Wiki Sections

Software

PoweredBy

Page History: Concurrency Exceptions - Entity Framework 6 and EF Core

Compare Page Revisions



« Older Revision - Back to Page History - Newer Revision »


Page Revision: Fri, Jan 17, 2020, 8:18 AM


Overview

This article outlines the steps to handle concurrency exceptions in Entity Framework 6.

Concurrency exceptions happen only on entities/tables that implement a row version field. They occur when EF detects that an underlying data record has changed since it was first retrieved. This frequently happens because two processes or users are trying to edit the record simultaneously. (Note that a concurrency exception is only relevant for updates — not inserts or deletes.

References


Implementation

Data Model

The entity/table that we want to implement optimistic concurrency on must have a field similar to the following.

[Timestamp]
public byte[] RowVersion { get; set; }

Exception Handling and Retry Logic

var done = false;
var iterNum = 1;
var maxIterations = 5;

do
{
    try
    {

        LoggingEngine.Info($"Starting Iteration {iterNum}.");

        /*  TODO: Implement logic to update record. */

        db.SaveChanges();

        done = true;
    }
    catch (SqlException ex) when (ex.Number == 1205) // 1205 = deadlock victim
    {
        iterNum++;
        done = (iterNum >= maxIterations);
        if (done)
        {
            LoggingEngine.Exception($"Deadlock exception while trying to "
                + $"do stuff - iteration {iterNum}. EXITING!", ex);
        }
        else
        {
            LoggingEngine.Exception($"Deadlock exception while trying to "
                + $"do stuff - iteration {iterNum}. Retrying operation.", ex);
        }
    }
    catch (DbUpdateConcurrencyException ex)
    {
        iterNum++;
        done = (iterNum > maxIterations);

        if (done)
        {
            LoggingEngine.Exception($"Concurrency exception while trying to " 
                + $"do stuff - iteration {iterNum-1}. EXITING!", ex);
        }
        else
        {
            LoggingEngine.Exception($"Concurrency exception while trying to "
                + $"do stuff - iteration {iterNum-1}. Retrying.", ex);

            foreach (var en in ex.Entries)
            {
                en.Reload(); // RELOAD = database wins
            }
        }
    }
    catch (Exception ex)
    {
        done = true;
        LoggingEngine.Exception($"Exception while trying to do stuff", ex);
    }
} while (!done);

ScrewTurn Wiki version 3.0.1.400. Some of the icons created by FamFamFam. Except where noted, all contents Copyright © 1999-2024, Patrick Jasinski.