EF Core Concurrency Tokens: Preventing Lost Updates in SQL Server

September 21, 2025 · 7 min

Two users edit the same customer record simultaneously. User A updates the phone number, User B changes the address. User A saves first, then User B saves. Result: the phone number update disappears.

This is the classic lost update problem, and it happens more often than you think in production web applications. EF Core concurrency tokens solve this elegantly without the complexity of database locks.

The Lost Update Problem

Without concurrency control, this scenario plays out daily in production:

// User A loads customer
var customer = await context.Customers.FindAsync(customerId);
customer.Phone = "555-0123";

// User B loads the same customer (before A saves)
var customer2 = await context.Customers.FindAsync(customerId);
customer2.Address = "123 New Street";

// User A saves first
await context.SaveChangesAsync(); // Phone updated

// User B saves second  
await context.SaveChangesAsync(); // Address updated, but phone reverted!

User B’s save overwrote User A’s phone number change because EF Core generated an UPDATE statement based on the original values User B loaded. The phone number silently reverted to its original value.

Concurrency Tokens to the Rescue

Concurrency tokens enable optimistic concurrency control. EF Core includes the token value in UPDATE and DELETE statements, ensuring the operation only succeeds if no one else modified the record:

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; } …

Read more