Last active
January 29, 2021 17:24
-
-
Save GFoley83/3e0c6e3a5ca36204937aaa62f13e7a0f to your computer and use it in GitHub Desktop.
MediatR pipeline for retrying Db deadlocks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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