Concurrency Tokens
Note
Please read the general Entity Framework Core docs on concurrency tokens.
Entity Framework Core supports the concept of optimistic concurrency - a property on your entity is designated as a concurrency token, and EF Core detects concurrent modifications by checking whether that token has changed since the entity was read.
The PostgreSQL xmin system column
Although applications can update concurrency tokens themselves, we frequently rely on the database automatically updating a column on update - a "last modified" timestamp, an SQL Server rowversion, etc. Unfortunately PostgreSQL doesn't have such auto-updating columns - but there is one feature that can be used for concurrency token. All PostgreSQL tables have a set of implicit and hidden system columns, among which xmin holds the ID of the latest updating transaction. Since this value automatically gets updated every time the row is changed, it is ideal for use as a concurrency token.
You can map a uint property to the PostgreSQL xmin system column using the standard EF Core mechanisms:
public class SomeEntity
{
public int Id { get; set; }
[Timestamp]
public uint Version { get; set; }
}
Database concurrency failures
Starting with version 11.0, PostgreSQL serialization failures (40001) and deadlocks (40P01) during SaveChanges() or SaveChangesAsync() are reported as DbUpdateConcurrencyException, with the original PostgresException as the inner exception. This also covers failures during the automatic transaction commit performed by SaveChanges. An explicit application call to commit a transaction is not covered by this conversion.
As with other concurrency failures, the application must decide whether and how to retry the operation. See the EF Core concurrency documentation and execution strategies.