Verbindungsresilienz und Wiederholungs LogikConnection resiliency and retry logic

Hinweis

Nur EF6 und höher: Die Features, APIs usw., die auf dieser Seite erläutert werden, wurden in Entity Framework 6 eingeführt.EF6 Onwards Only - The features, APIs, etc. discussed in this page were introduced in Entity Framework 6. Wenn Sie eine frühere Version verwenden, gelten manche Informationen nicht.If you are using an earlier version, some or all of the information does not apply.

Anwendungen, die eine Verbindung mit einem Datenbankserver herstellen, waren aufgrund von Back-End-Fehlern und Netzwerk Instabilität immer anfällig für Verbindungsunterbrechungen.Applications connecting to a database server have always been vulnerable to connection breaks due to back-end failures and network instability. In einer LAN-basierten Umgebung, die mit dedizierten Datenbankservern arbeitet, sind diese Fehler jedoch selten genug, dass die zusätzliche Logik zur Behandlung dieser Fehler nicht häufig erforderlich ist.However, in a LAN based environment working against dedicated database servers these errors are rare enough that extra logic to handle those failures is not often required. Mit dem Anstieg von cloudbasierten Datenbankservern wie Windows Azure SQL-Datenbank und Verbindungen über weniger zuverlässige Netzwerke kommt es nun häufiger vor, dass Verbindungsunterbrechungen auftreten.With the rise of cloud based database servers such as Windows Azure SQL Database and connections over less reliable networks it is now more common for connection breaks to occur. Dies liegt möglicherweise an der Abwehr von Techniken, die clouddatenbanken verwenden, um die Fairness des Diensts zu gewährleisten, z. b. die Verbindungs Drosselung oder eine Instabilität im Netzwerk, die vorübergehende Timeouts und andere vorübergehende Fehler verursacht.This could be due to defensive techniques that cloud databases use to ensure fairness of service, such as connection throttling, or to instability in the network causing intermittent timeouts and other transient errors.

Verbindungsresilienz bezieht sich auf die Fähigkeit von EF, Befehle, die aufgrund dieser Verbindungsunterbrechungen fehlschlagen, automatisch zu wiederholen.Connection Resiliency refers to the ability for EF to automatically retry any commands that fail due to these connection breaks.

Ausführungs StrategienExecution Strategies

Die Verbindungs Wiederholung erfolgt durch eine Implementierung der idbexecutionstrategy-Schnittstelle.Connection retry is taken care of by an implementation of the IDbExecutionStrategy interface. Implementierungen der idbexecutionstrategy-Strategie sind dafür verantwortlich, einen Vorgang zu akzeptieren und, wenn eine Ausnahme auftritt, festzustellen, ob eine Wiederholung angemessen ist, und den Vorgang zu wiederholen, wenn dies der Fall ist.Implementations of the IDbExecutionStrategy will be responsible for accepting an operation and, if an exception occurs, determining if a retry is appropriate and retrying if it is. Es gibt vier Ausführungs Strategien, die mit EF ausgeliefert werden:There are four execution strategies that ship with EF:

  1. Defaultexecutionstrategy: Diese Ausführungs Strategie führt keinen Wiederholungsversuch für Vorgänge aus. Dies ist die Standardeinstellung für andere Datenbanken als SQL Server.DefaultExecutionStrategy: this execution strategy does not retry any operations, it is the default for databases other than sql server.
  2. Defaultionqlexecutionstrategy: Dies ist eine interne Ausführungs Strategie, die standardmäßig verwendet wird.DefaultSqlExecutionStrategy: this is an internal execution strategy that is used by default. Diese Strategie führt nicht zu einem erneuten Versuch, sondern schließt alle Ausnahmen ein, die vorübergehend sein könnten, um Benutzer darüber zu informieren, dass Sie möglicherweise die verbindungsresilienz aktivieren möchten.This strategy does not retry at all, however, it will wrap any exceptions that could be transient to inform users that they might want to enable connection resiliency.
  3. Dbexecutionstrategy: Diese Klasse eignet sich als Basisklasse für andere Ausführungs Strategien, einschließlich ihrer eigenen benutzerdefinierten.DbExecutionStrategy: this class is suitable as a base class for other execution strategies, including your own custom ones. Es implementiert eine exponentielle Wiederholungs Richtlinie, bei der der anfängliche Wiederholungsversuch mit einer Verzögerung von 0 (null) erfolgt, und die Verzögerung erhöht sich exponentiell, bis die maximale Anzahl der Wiederholungs Versuche übertrifft.It implements an exponential retry policy, where the initial retry happens with zero delay and the delay increases exponentially until the maximum retry count is hit. Diese Klasse verfügt über eine abstrakte Methode "schuldretryon", die in abgeleiteten Ausführungs Strategien implementiert werden kann, um zu steuern, welche Ausnahmen wiederholt werden sollen.This class has an abstract ShouldRetryOn method that can be implemented in derived execution strategies to control which exceptions should be retried.
  4. Sqlazureexecutionstrategy: Diese Ausführungs Strategie erbt von dbexecutionstrategy und führt einen Wiederholungsversuch für Ausnahmen aus, die bekanntermaßen bei der Arbeit mit Azure SQL-Datenbank vorübergehend sind.SqlAzureExecutionStrategy: this execution strategy inherits from DbExecutionStrategy and will retry on exceptions that are known to be possibly transient when working with Azure SQL Database.

Hinweis

Die Ausführungs Strategien 2 und 4 sind im SQL Server-Anbieter enthalten, der im Lieferumfang von EF enthalten ist, das sich in der EntityFramework. SqlServer-Assembly befindet und für die Arbeit mit SQL Server konzipiert ist.Execution strategies 2 and 4 are included in the Sql Server provider that ships with EF, which is in the EntityFramework.SqlServer assembly and are designed to work with SQL Server.

Aktivieren einer Ausführungs StrategieEnabling an Execution Strategy

Die einfachste Möglichkeit, EF die Verwendung einer Ausführungs Strategie mitzuteilen, ist die Methode "" der Methode "" der Klasse " dbconfiguration ":The easiest way to tell EF to use an execution strategy is with the SetExecutionStrategy method of the DbConfiguration class:

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

Dieser Code weist EF an, beim Herstellen einer Verbindung mit SQL Server sqlazureexecutionstrategy zu verwenden.This code tells EF to use the SqlAzureExecutionStrategy when connecting to SQL Server.

Konfigurieren der Ausführungs StrategieConfiguring the Execution Strategy

Der Konstruktor von sqlazureexecutionstrategy kann zwei Parameter akzeptieren: "maxRetryCount" und "MaxDelay".The constructor of SqlAzureExecutionStrategy can accept two parameters, MaxRetryCount and MaxDelay. Die Anzahl der maxretry-Werte ist die maximale Anzahl von Wiederholungs versuchen für die Strategie.MaxRetry count is the maximum number of times that the strategy will retry. MaxDelay ist ein TimeSpan-Wert, der die maximale Verzögerung zwischen Wiederholungs versuchen darstellt, die von der Ausführungs Strategie verwendet werden.The MaxDelay is a TimeSpan representing the maximum delay between retries that the execution strategy will use.

Führen Sie die folgenden Schritte aus, um die maximale Anzahl von Wiederholungen auf 1 und die maximale Verzögerung auf 30 Sekunden festzulegen:To set the maximum number of retries to 1 and the maximum delay to 30 seconds you would execute the following:

public class MyConfiguration : DbConfiguration
{
    public MyConfiguration()
    {
        SetExecutionStrategy(
            "System.Data.SqlClient",
            () => new SqlAzureExecutionStrategy(1, TimeSpan.FromSeconds(30)));
    }
}

Sqlazureexecutionstrategy wird beim ersten Auftreten eines vorübergehenden Fehlers sofort wiederholt, verzögert sich jedoch zwischen den einzelnen Wiederholungen, bis entweder die maximale Wiederholungs Grenze überschritten wird oder die Gesamtzeit die maximale Verzögerung erreicht.The SqlAzureExecutionStrategy will retry instantly the first time a transient failure occurs, but will delay longer between each retry until either the max retry limit is exceeded or the total time hits the max delay.

Bei den Ausführungs Strategien wird nur eine begrenzte Anzahl von Ausnahmen wiederholt, die normalerweise vorübergehend sind. Sie müssen weiterhin andere Fehler behandeln und die Ausnahme "retrylimitexcegetretenen" abfangen, wenn ein Fehler nicht vorübergehend ist oder zu lang ist, um sich selbst aufzulösen.The execution strategies will only retry a limited number of exceptions that are usually transient, you will still need to handle other errors as well as catching the RetryLimitExceeded exception for the case where an error is not transient or takes too long to resolve itself.

Bei der Verwendung einer Wiederholungs Ausführungs Strategie gibt es einige bekannte Einschränkungen:There are some known of limitations when using a retrying execution strategy:

Streaming-Abfragen werden nicht unterstützt.Streaming queries are not supported

Standardmäßig puffert EF6 und höhere Versionen Abfrageergebnisse, anstatt Sie zu streamen.By default, EF6 and later version will buffer query results rather than streaming them. Wenn die Ergebnisse gestreamt werden sollen, können Sie die asstreaming-Methode verwenden, um eine LINQ to Entities Abfrage in das Streaming zu ändern.If you want to have results streamed you can use the AsStreaming method to change a LINQ to Entities query to streaming.

using (var db = new BloggingContext())
{
    var query = (from b in db.Blogs
                orderby b.Url
                select b).AsStreaming();
    }
}

Streaming wird nicht unterstützt, wenn eine Wiederholungs Ausführungs Strategie registriert wird.Streaming is not supported when a retrying execution strategy is registered. Diese Einschränkung ist vorhanden, da die Verbindung die Ergebnisse, die zurückgegeben werden, auf dem Weg ablegen könnte.This limitation exists because the connection could drop part way through the results being returned. In diesem Fall muss EF die gesamte Abfrage erneut ausführen, kann jedoch nicht zuverlässig festzustellen, welche Ergebnisse bereits zurückgegeben wurden (die Daten haben sich möglicherweise seit dem Senden der ersten Abfrage geändert, Ergebnisse können in einer anderen Reihenfolge zurückgegeben werden, die Ergebnisse haben möglicherweise keinen eindeutigen Bezeichner usw.).When this occurs, EF needs to re-run the entire query but has no reliable way of knowing which results have already been returned (data may have changed since the initial query was sent, results may come back in a different order, results may not have a unique identifier, etc.).

Vom Benutzer initiierte Transaktionen werden nicht unterstützt.User initiated transactions are not supported

Wenn Sie eine Ausführungs Strategie konfiguriert haben, die zu Wiederholungen führt, gibt es einige Einschränkungen bei der Verwendung von Transaktionen.When you have configured an execution strategy that results in retries, there are some limitations around the use of transactions.

Standardmäßig führt EF innerhalb einer Transaktion alle Datenbankupdates aus.By default, EF will perform any database updates within a transaction. Sie müssen nichts tun, um dies zu ermöglichen. EF führt dies immer automatisch durch.You don’t need to do anything to enable this, EF always does this automatically.

Im folgenden Code wird z. b. "SaveChanges" automatisch innerhalb einer Transaktion ausgeführt.For example, in the following code SaveChanges is automatically performed within a transaction. Wenn SaveChanges nach dem Einfügen einer der neuen Standorte fehlschlagen würde, wird für die Transaktion ein Rollback ausgeführt, und es werden keine Änderungen auf die Datenbank angewendet.If SaveChanges were to fail after inserting one of the new Site’s then the transaction would be rolled back and no changes applied to the database. Außerdem bleibt der Kontext in einem Zustand, in dem SaveChanges erneut aufgerufen werden kann, um die Änderungen zu übernehmen.The context is also left in a state that allows SaveChanges to be called again to retry applying the changes.

using (var db = new BloggingContext())
{
    db.Blogs.Add(new Site { Url = "http://msdn.com/data/ef" });
    db.Blogs.Add(new Site { Url = "http://blogs.msdn.com/adonet" });
    db.SaveChanges();
}

Wenn keine Wiederholungs Ausführungs Strategie verwendet wird, können Sie mehrere Vorgänge in einer einzelnen Transaktion umschließen.When not using a retrying execution strategy you can wrap multiple operations in a single transaction. Der folgende Code umschließt z. b. zwei SaveChanges-Aufrufe in einer einzelnen Transaktion.For example, the following code wraps two SaveChanges calls in a single transaction. Wenn ein Teil eines der beiden Vorgänge fehlschlägt, wird keine der Änderungen angewendet.If any part of either operation fails then none of the changes are applied.

using (var db = new BloggingContext())
{
    using (var trn = db.Database.BeginTransaction())
    {
        db.Blogs.Add(new Site { Url = "http://msdn.com/data/ef" });
        db.Blogs.Add(new Site { Url = "http://blogs.msdn.com/adonet" });
        db.SaveChanges();

        db.Blogs.Add(new Site { Url = "http://twitter.com/efmagicunicorns" });
        db.SaveChanges();

        trn.Commit();
    }
}

Dies wird nicht unterstützt, wenn eine Wiederholungs Ausführungs Strategie verwendet wird, da EF keine früheren Vorgänge kennt und die Wiederholungs Versuche ausgeführt werden.This is not supported when using a retrying execution strategy because EF isn’t aware of any previous operations and how to retry them. Wenn beispielsweise die zweite SaveChanges fehlgeschlagen ist, verfügt EF nicht mehr über die erforderlichen Informationen, um den ersten SaveChanges-Befehl zu wiederholen.For example, if the second SaveChanges failed then EF no longer has the required information to retry the first SaveChanges call.

Lösung: Manuelles Abrufen der Ausführungs StrategieSolution: Manually Call Execution Strategy

Die Lösung besteht darin, die Ausführungs Strategie manuell zu verwenden und ihr den gesamten Logik Satz zuzuweisen, der ausgeführt werden soll, damit Sie alles wiederholen kann, wenn einer der Vorgänge fehlschlägt.The solution is to manually use the execution strategy and give it the entire set of logic to be run, so that it can retry everything if one of the operations fails. Wenn eine von dbexecutionstrategy abgeleitete Ausführungs Strategie ausgeführt wird, wird die in SaveChanges verwendete implizite Ausführungs Strategie angehalten.When an execution strategy derived from DbExecutionStrategy is running it will suspend the implicit execution strategy used in SaveChanges.

Beachten Sie, dass alle Kontexte innerhalb des Codeblocks erstellt werden müssen, um erneut versucht werden zu können.Note that any contexts should be constructed within the code block to be retried. Dadurch wird sichergestellt, dass für jeden Wiederholungsversuch ein sauberer Zustand gestartet wird.This ensures that we are starting with a clean state for each retry.

var executionStrategy = new SqlAzureExecutionStrategy();

executionStrategy.Execute(
    () =>
    {
        using (var db = new BloggingContext())
        {
            using (var trn = db.Database.BeginTransaction())
            {
                db.Blogs.Add(new Blog { Url = "http://msdn.com/data/ef" });
                db.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/adonet" });
                db.SaveChanges();

                db.Blogs.Add(new Blog { Url = "http://twitter.com/efmagicunicorns" });
                db.SaveChanges();

                trn.Commit();
            }
        }
    });