es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Se necesita una forma integrada de agregar la Resiliencia a Deadlock a Dapper para repositorios existentes sin alterarlos.

Necesito hacer que todos los repositorios existentes (alrededor de 30+) sean tolerantes a fallas en cuanto a los bloqueos y puedan recuperarse de ellos con un enfoque de registro y espera.

He logrado hacerlo con éxito: He respondido a continuación con una política personalizada de SqlResiliencyPolicy utilizando Polly después de investigar y adaptarla al proyecto.

Pero, lo que busco: La forma actual (indicada a continuación) me exige o bien envolver todas las llamadas existentes a la base de datos con await _policy.ExecuteAsync O bien proporcionar sobrecargas personalizadas que acepten el parámetro IAsyncPolicy y luego llamen al método previsto. Una especie de extensión a IDbConnection:

public static Task<T> GetAsync<T>(this IDbConnection connection, object primaryKey, IAsyncPolicy policy) => return await _policy.ExecuteAsync(async () => GetAsync<T> (...));

De ambas formas, necesito cambiar todos mis 30+ repositorios. Sin embargo, ¿hay alguna forma integrada en Dapper/otros enfoques donde podemos

“configurar una política en el inicio y, mágicamente, todas las llamadas a la base de datos con Dapper se vuelven resistentes (vuelven a su mecanismo tolerante a fallas), similar a las formas de la resiliencia de los clientes HTTP, donde se agrega una política mientras se registra un cliente”

Con esto: los cambios en el código se reducen al mínimo, no es necesario tocar los repositorios, solo el inicio.

Tengo un enfoque a continuación y necesito una mejora sobre él.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Una manera de lograr esto es utilizar los métodos de extensión IDbConnection en Dapper.Contrib para aplicar automáticamente la política de Polly a todas las llamadas a la base de datos.

    Primero, crea una política personalizada de resiliencia de Sql utilizando Polly, como mencionaste. Luego, crea un método de extensión IDbConnection que envuelve todas las llamadas a los métodos de Dapper.Contrib con la política de Polly. Aquí hay un ejemplo:

    public static async Task<><t>> GetAllAsync<t>(this IDbConnection connection, IAsyncPolicy policy = null)
    {
        policy = policy ?? Policy.NoOpAsync();
    
        return await policy.ExecuteAsync(async () => await connection.GetAllAsync<t>());
    }
    

    De manera similar, puedes crear métodos de extensión para otros métodos de Dapper.Contrib como GetAsync, InsertAsync, UpdateAsync, etc.

    En el inicio de tu aplicación, puedes configurar la política y registrar los métodos de extensión IDbConnection de la siguiente manera:

    services.AddDbContext<yourdbcontext>();
    
    var sqlResiliencyPolicy = GetSqlResiliencyPolicy(); // tu política personalizada de resiliencia de Sql creada con Polly
    
    DapperExtensions.DapperAsyncExtensions.GetListAsync = (c, t) => c.GetListAsync(t, sqlResiliencyPolicy);
    DapperExtensions.DapperAsyncExtensions.GetAsync = (c, id) => c.GetAsync(id, sqlResiliencyPolicy);
    DapperContrib.Extensions.SqlMapperExtensions.InsertAsync = (c, entity) => entity.InsertAsync(sqlResiliencyPolicy);
    DapperContrib.Extensions.SqlMapperExtensions.UpdateAsync = (c, entity) => entity.UpdateAsync(sqlResiliencyPolicy);
    DapperContrib.Extensions.SqlMapperExtensions.DeleteAsync = (c, entity) => entity.DeleteAsync(sqlResiliencyPolicy);
    

    Con este enfoque, puedes minimizar los cambios de código y solo necesitas modificar el inicio de tu aplicación para hacer que todos los repositorios existentes sean tolerantes a fallos debido a un deadlock.

Comments are closed.