Roadmap › Entity Framework (EF6 & EF Core) › Module: Saving Data
Lessons in this course (15)

11. Concurrency control

Intermediate★ Must knowLesson 11 of 15
csharp
public class Product
{
    public int Id { get; set; }
    public decimal Price { get; set; }
    [Timestamp] public byte[] RowVersion { get; set; } = [];      // SQL Server rowversion
}

try
{
    product.Price = newPrice;
    await db.SaveChangesAsync();          // UPDATE ... WHERE Id = @id AND RowVersion = @originalVersion
}
catch (DbUpdateConcurrencyException ex)
{
    var entry = ex.Entries.Single();
    var dbValues = await entry.GetDatabaseValuesAsync();
    // options: client wins (refresh original values and retry), store wins (reload), or ask the user to merge
}

Optimistic concurrency (rowversion / IsConcurrencyToken()): no locks; detect conflicts on save — default choice for web apps. Pessimistic (locks: SELECT ... WITH (UPDLOCK), serializable transactions): prevents conflicts but reduces throughput.