I want to ensure that when I do a context.SaveChanges()
, this is retried because the database might be temporarily down.
So far all I’ve found involves writing a lot of code that I’d then need to maintain, so is there something ready, an out-of-the-box tool, that I can use for resiliency?
3
Answers
I’ve created a small library called
ResilientSaveChanges.EFCore
that allows resilientcontext.SaveChanges
/SaveChangesAsync
in Entity Framework Core, logging of long-running transactions and limiting of concurrent SaveChanges. It’s straight to the point.Available on GitHub and NuGet. Tried and tested in production on multiple private projects.
Yes, connection resiliency is available in EF Core. For MySQL, it’s available through the Pomelo driver’s
EnabelRetryOnFailure()
option. The Github Blame shows this was added 5 years ago which is a bit surprising. An overload added 3 years ago allows specifying extra errors to retry.This code taken from one of the integration tests shows how it’s used:
Without parameters
EnableRetryOnFailure()
uses the default retry count and maximum delay which are 6 and 30 seconds.The third parameter is an
ICollection<int>
of additional errors to retry.By default, the MySqlTransientExceptionDetector class specifies that only transient exceptions are retried, ie those that have the
IsTransient
property set, or timeout exceptions.As @PanagiotisKanavos already pointed out, Pomelo already has connection resiliency support.
The simplest way to use it, is to enable the default strategy:
It will retry up to six times, incrementally waiting for longer periods between retries (but not longer than 30 seconds).
If you want to configure the retry strategy, use the following overload instead:
If you want full control over all aspects of the execution strategy, you can inject your own implementation (that either inherits from
MySqlExecutionStrategy
or directly implementsIExecutionStrategy
):