EF6 Suspendable Execution Strategy

Posted on August 19, 2013. Filed under: Entity Framework, Visual Studio | Tags: , , , , , , , |

EF6 introduces the new connection resiliency feature that allows for automatic retries of failed database operations. I was recently writing some documentation for EF6 and came across a scenario where it would be useful to have a global switch to enable/disable retry logic. Such a switch isn’t built into EF6, although we do have an item on our backlog to possibly enable this in the future.

Fortunately it’s actually pretty easy to implement this flag yourself.

Note: The code in this post is based on the latest nightly build and does not work with EF6.0.0-beta1.

The Always-On Default

The easiest way to register an execution strategy in EF6 is to make use of code-based configuration. Here is a typical configuration class that you might write to enable the SqlAzureExecutionStrategy (an execution strategy that will retry the known retryable exceptions when working with SQL Azure).

using System.Data.Entity;
using System.Data.Entity.SqlServer;

namespace Demo
{
    public class MyConfiguration : DbConfiguration
    {
        public MyConfiguration()
        {
            this.SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
        }
    }
}

Allowing Suspension

Because EF will get a new execution strategy for every operation it performs we can introduce some conditional logic to return either the default (non-retrying) strategy or the SQL Azure (retying) strategy based on a switch.

Notice that we are getting/setting the value for the flag from CallContext. This ensures that our flag works correctly if we are using the new async query/save feature in EF6.

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;
using System.Runtime.Remoting.Messaging;

namespace Demo
{
    public class MyConfiguration : DbConfiguration
    {
        public MyConfiguration()
        {
            this.SetExecutionStrategy("System.Data.SqlClient", () => SuspendExecutionStrategy
              ? (IDbExecutionStrategy)new DefaultExecutionStrategy()
              : new SqlAzureExecutionStrategy());
        }

        public static bool SuspendExecutionStrategy
        {
            get
            {
                return (bool?)CallContext.LogicalGetData("SuspendExecutionStrategy") ?? false;
            }
            set
            {
                CallContext.LogicalSetData("SuspendExecutionStrategy", value);
            }
        }
    }
}

Using the Flag

Now we can use the flag to disable retry logic for certain operations.

using (var db = new BloggingContext())
{
  MyConfiguration.SuspendExecutionStrategy = true;

  // Perform without retry logic
  db.Blogs.Add(new Blog { Url = "romiller.com" });
  db.SaveChanges();

  MyConfiguration.SuspendExecutionStrategy = false;

}

When Would I Use This?

The most common reason you might use this is when performing an operation that is not supported by retry logic – such as user initiated transactions. This was the piece of documentation I was writing when I put the original code together, so you can find more info on this particular scenario on our MSDN site.

Make a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

    About

    Rowan works as a Program Manager for the ADO.NET Entity Framework team at Microsoft. He speaks at technical conferences and blogs at romiller.com. Rowan lives in Seattle, Washington with his wife Athalie. Prior to moving to the US he resided in the small state of Tasmania in Australia. Outside of technology Rowan's passions include snowboarding, mountain biking, horse riding, rock climbing and pretty much anything else that involves being active. The primary focus of his life, however, is to follow Jesus.

    RSS

    Subscribe Via RSS

    • Subscribe with Bloglines
    • Add your feed to Newsburst from CNET News.com
    • Subscribe in Google Reader
    • Add to My Yahoo!
    • Subscribe in NewsGator Online
    • The latest comments to all posts in RSS

    Meta

Liked it here?
Why not try sites on the blogroll...

Follow

Get every new post delivered to your Inbox.

Join 162 other followers

%d bloggers like this: