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

Concurrency Exceptions - Entity Framework 6

RSS
Modified on Fri, Jan 17, 2020, 8:18 AM by Administrator Categorized as Entity Framework Code First, ┬ĚNet Framework

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-2020, Patrick Jasinski.