Skip to content

Instantly share code, notes, and snippets.

@GFoley83
Last active January 29, 2021 17:24
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save GFoley83/3e0c6e3a5ca36204937aaa62f13e7a0f to your computer and use it in GitHub Desktop.
Save GFoley83/3e0c6e3a5ca36204937aaa62f13e7a0f to your computer and use it in GitHub Desktop.
MediatR pipeline for retrying Db deadlocks
using System;
using System.Data.Common;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
namespace Foo
{
public class DbDeadlockRetryHandlerProcessor<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next)
{
// Retry a deadlock 5 times
return await HandleWithCountDown(next, 5);
}
private async Task<TResponse> HandleWithCountDown(RequestHandlerDelegate<TResponse> next, int count)
{
TResponse response;
try
{
response = await next();
}
catch (Exception ex)
{
// Only catch deadlock exceptions
if (count <= 0 || !IsDeadlockException(ex))
{
throw;
}
await Task.Delay(300);
response = await HandleWithCountDown(next, count - 1);
}
return response;
}
private static bool IsDeadlockException(Exception ex)
{
while (ex != null)
{
if (ex is DbException && ex.Message.Contains("deadlock"))
{
return true;
}
ex = ex.InnerException;
}
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment