2011-05-02 17 views
14

Estoy escribiendo una aplicación para Windows Azure. Estoy usando Entity Framework para acceder a SQL Azure. Debido a la aceleración y otros mecanismos en SQL Azure, necesito asegurarme de que mi código realice reintentos si una instrucción SQL ha fallado. Estoy tratando de encontrar un método sólido para hacer esto.Uso de Entity Framework con SQL Azure - Confiabilidad

(En el siguiente código, ObjectSet devuelve mi EFContext.CreateObjectSet())

Digamos que tengo una función como esta:

public Product GetProductFromDB(int productID) 
    { 
    return ObjectSet.Where(item => item.Id = productID).SingleOrDefault(); 
    } 

Ahora bien, esta función realiza ningún reintento y fallará antes o más tarde en SQL Azure. Una solución ingenua sería hacer algo como esto:

public Product GetProductFromDB(int productID) 
    { 
    for (int i = 0; i < 3; i++) 
    { 
     try 
     { 
      return ObjectSet.Where(item => item.Id = productID).SingleOrDefault(); 
     } 
     catch 
     { 

     } 
    } 
    } 

Por supuesto, esto tiene varios inconvenientes. Volveré a intentarlo independientemente de la falla de SQL (el intento de reintento es una pérdida de tiempo si es una violación de clave principal, por ejemplo), volveré a intentarlo inmediatamente sin pausa, y así sucesivamente.

Mi próximo paso fue comenzar a usar la biblioteca de manejo de fallas transitorias de Microsoft. Contiene RetryPolicy que me permite separar la lógica de reintento a partir del código de consulta real:

public Product GetProductFromDB(int productID) 
    { 
    var retryPolicy = new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(5); 

    var result = _retryPolicy.ExecuteAction(() => 
     { 
      return ObjectSet.Where(item => item.Id = productID).SingleOrDefault; 
     }); 

    return result; 
    } 

La última solución anterior se describe como un http://blogs.msdn.com/b/appfabriccat/archive/2010/10/28/best-practices-for-handling-transient-conditions-in-sql-azure-client-applications.aspx mejores prácticas para manejo de transitorios Condiciones de aplicación de cliente de SQL Azure (Patrones de uso avanzado de sección) .

Si bien esto es un paso adelante, todavía tengo que recordar utilizar la clase RetryPolicy cada vez que quiero acceder a la base de datos a través de Entity Framework. En un equipo de varias personas, esto es algo que es fácil pasar por alto. Además, el código anterior es un poco complicado en mi opinión.

Lo que me gustaría es una forma de hacer cumplir que los reintentos siempre se usan, todo el tiempo. La biblioteca Transient Fault Handling contiene una clase llamada ReliableSQLConnection pero no puedo encontrar una forma de usar esto con Entity Framework.

¿Alguna buena sugerencia para este problema?

Respuesta

7

Después de las observaciones anteriores, Microsoft creó la biblioteca de manejo de fallas transitorias, que "incluye soporte directo para trabajar con SQL Azure a través de la clase ReliableSqlConnection".

http://msdn.microsoft.com/en-us/library/hh680899(v=pandp.50).aspx

La mayoría de los desarrolladores que quieran utilizar Azure se encuentran por encima de la que será de gran ayuda.

+0

Esta respuesta no responde a la pregunta - la pregunta era ¿es posible no tiene que acordarse de usar el RetryPolicy para cada llamada. El enlace que ha proporcionado no muestra cómo hacerlo y, de hecho, sugiere que debe ajustar cada llamada. –

3

Si utiliza Entity Framework 6 (actualmente en alfa) entonces hay algún nuevo soporte incorporado para los reintentos transitorios con la base de datos SQL Azure (con un poco de configuración): http://entityframework.codeplex.com/wikipage?title=Connection%20Resiliency%20Spec

He creado una biblioteca que le permite configurar Entity Framework para volver a intentarlo utilizando el bloque de manejo de fallas sin necesidad de cambiar cada llamada a la base de datos; en general, solo necesitará cambiar su archivo de configuración y posiblemente una o dos líneas de código.

Esto le permite usarlo para Entity Framework < v6 o Linq To Sql.

https://github.com/robdmoore/ReliableDbProvider

Cuestiones relacionadas