EF 4.0 : Save Changes Retry Logic

Posted by BGR on Stack Overflow See other posts from Stack Overflow or by BGR
Published on 2010-06-11T14:49:00Z Indexed on 2010/06/11 14:52 UTC
Read the original article Hit count: 462

Filed under:

Hi,

I would like to implement an application wide retry system for all entity SaveChanges method calls.

Technologies:
Entity 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);
    }
}   

}

The problem:

How can I run the StoreDB.SaveChanges to retry on a new DB context after an error occured? Something simular to Detach/Attach might come in handy.

Thanks in advance! Bart

© Stack Overflow or respective owner

Related posts about entity-framework-4