Consider raising provider-specific concurrency exceptions as DbUpdateConcurrencyException
- 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
Assessment
This issue has not been assessed yet.