dotnet / dotnet/efcore

Consider raising provider-specific concurrency exceptions as DbUpdateConcurrencyException

Open
#33,068 21 comments 0 reactions 0 assignees View on GitHub
area-save-changes customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

DbUpdateConcurrencyException is currently only thrown for an EF concurrency-token related failure, i.e. when the rows-affected from the database don't match the expectation.

There are various other concurrency errors that are raised directly from the database - deadlocks, write conflicts in snapshot isolation mode (PG repeatable read), serialization errors in serializable isolation mode. There's no conceptual difference between these and EF's error; in fact, snapshot mode specifically optimistically handles the exact same case that EF's concurrency token handles - write conflicts. So it could make sense to provide a provider hook that would allow wrapping such exceptions in DbUpdateConcurrencyException; this would allow users to only need to catch that for retries etc.

On the downside, note that this would be a small breaking change, as applications currently handling e.g. deadlock retrying by catching SqlException would suddenly start getting a DbUpdateConcurrencyException. They're probably already doing that if they're using concurrency tokens, but not everyone uses them. In addition, EF has so far refrained from interpreting/doing stuff to provider exceptions, simply bubbling them up; this may be useful to users as provider exceptions look and behave the same with or without EF, rather than being caught and rethrown in some other way as is being proposed here.

Note also the relationship with [DbException.IsTransient](https://learn.microsoft.com/en-us/dotnet/api/system.data.common.dbexception.istransient?view=net-7.0#system-data-common-dbexception-istransient), through which a provider can indicate that an exception may be transient and it makes sense to retry ([not yet implemented on SqlClient](https://github.com/dotnet/SqlClient/issues/649)). Though not all transient exceptions represent concurrency errors.

Raised by @benjamincburns in https://github.com/npgsql/efcore.pg/issues/3084

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.