2010-06-11 5 views
3

Je souhaite implémenter un système de réessai large pour tous les appels de méthode entité SaveChanges.EF 4.0: Enregistrer les modifications Retry Logic

Technologies:
Entité Framework 4.0
.Net 4,0

namespace Sample.Data.Store.Entities { 
    public partial class StoreDB 
    { 
     public override int SaveChanges(System.Data.Objects.SaveOptions options) 
     {    
      for (Int32 attempt = 1; ;) 
      { 

       try 
       { 
        return base.SaveChanges(options); 
       } 
       catch (SqlException sqlException) 
       { 
        // Increment Trys 
        attempt++; 

        // Find Maximum Trys 
        Int32 maxRetryCount = 5; 

        // Throw Error if we have reach the maximum number of retries 
        if (attempt == maxRetryCount) 
         throw; 

        // Determine if we should retry or abort. 
        if (!RetryLitmus(sqlException)) 
         throw; 
        else 
         Thread.Sleep(ConnectionRetryWaitSeconds(attempt)); 
       } 
      } 
     } 

     static Int32 ConnectionRetryWaitSeconds(Int32 attempt) 
     { 
      Int32 connectionRetryWaitSeconds = 2000; 

      // Backoff Throttling 
      connectionRetryWaitSeconds = connectionRetryWaitSeconds * 
       (Int32)Math.Pow(2, attempt); 

      return (connectionRetryWaitSeconds); 
     } 



     /// <summary> 
     /// Determine from the exception if the execution 
     /// of the connection should Be attempted again 
     /// </summary> 
     /// <param name="exception">Generic Exception</param> 
     /// <returns>True if a a retry is needed, false if not</returns> 
     static Boolean RetryLitmus(SqlException sqlException) 
     { 
     switch (sqlException.Number) 
      { 
       // The service has encountered an error 
       // processing your request. Please try again. 
       // Error code %d. 
       case 40197: 
       // The service is currently busy. Retry 
       // the request after 10 seconds. Code: %d. 
       case 40501: 
       //A transport-level error has occurred when 
       // receiving results from the server. (provider: 
       // TCP Provider, error: 0 - An established connection 
       // was aborted by the software in your host machine.) 
       case 10053: 
        return (true); 
      } 

      return (false); 
     } 
    } 
} 

Le problème:

Comment puis-je exécuter les StoreDB.SaveChanges pour recommencer un nouveau contexte DB après une erreur est survenue? Quelque chose de similaire à Detach/Attach peut être utile.

Merci d'avance! Bart

Répondre

0

Consultez le cadre de gestion des défaillances transitoires pour SQL Azure, here. C'est assez générique, et il est facile de le modifier pour inclure une nouvelle logique pour votre backend.

Questions connexes