One of the most common mistakes in multithreaded programming is assuming that operations on in-memory variables are automatically atomic.
They are not.
Even a simple statement like counter++; is actually composed of multiple steps:
If multiple threads execute this simultaneously, race conditions can occur and updates may be lost.
RowVersion is a blunt instrument for optimistic concurrency.
In EF Core, RowVersion treats every data mutation as concurrency-critical.
That assumption doesn’t always hold in real systems.
In read-heavy applications, entities often mix:
Title)ViewCount, LastSeen, HitCount)With RowVersion:
DbUpdateConcurrencyExceptionNot because of a semantic conflict ,
but because all mutations are treated equally.
A more intentional design is to scope concurrency to business intent, not storage changes.
Using [ConcurrencyCheck] on selected properties:
Concurrency is a modeling decision, not a framework default.
Design it around what should conflict, not what happened to change.
© vahid arya. All Rights Reserved.