Dela via


Felsöka tillfälliga anslutningsfel i SQL Database och SQL Managed Instance

gäller för:Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics

Den här artikeln beskriver hur du förhindrar, felsöker, diagnostiserar och åtgärdar anslutningsfel och tillfälliga fel som klientprogrammet stöter på när det interagerar med Azure SQL Database, Azure SQL Managed Instance och Azure Synapse Analytics. Lär dig hur du konfigurerar logik för återförsök, skapar anslutningssträngen och justerar andra anslutningsinställningar.

Tillfälliga fel (tillfälliga störningar)

Ett tillfälligt fel, även kallat ett tillfälligt fel, har en underliggande orsak som snart löser sig själv. En tillfällig orsak till tillfälliga fel är när Azure-systemet snabbt flyttar maskinvaruresurser till bättre belastningsutjämning av olika arbetsbelastningar. De flesta av dessa omkonfigurationshändelser avslutas på mindre än 60 sekunder. Under den här omkonfigurationstiden kan du ha problem med att ansluta till databasen i SQL Database. Program som ansluter till databasen bör skapas för att förvänta sig dessa tillfälliga fel. För att hantera dem implementerar du omprövningslogik i koden i stället för att visa dem för användare som programfel.

Om klientprogrammet använder ADO.NET informeras programmet om det tillfälliga felet genom att SqlExceptionkastas.

Anslutning mot kommando

Försök igen med SQL Database- och SQL Managed Instance-anslutningen eller upprätta den igen, beroende på följande:

  • Ett tillfälligt fel inträffar under ett anslutningsförsök

Försök ansluta igen efter en fördröjning på flera sekunder.

  • Ett tillfälligt fel inträffar under ett SQL Database- och SQL Managed Instance-frågekommando

Försök inte omedelbart med kommandot igen. Efter en fördröjning upprättar du i stället anslutningen på nytt. Försök sedan med kommandot igen.

Prova logiken igen för tillfälliga fel

Klientprogram som ibland stöter på ett tillfälligt fel är mer robusta när de innehåller logik för återförsök. När programmet kommunicerar med databasen i SQL Database via mellanprogram från tredje part frågar du leverantören om mellanprogrammet innehåller omprövningslogik för tillfälliga fel.

Principer för återförsök

  • Om felet är tillfälligt försöker du öppna en anslutning igen.
  • Försök inte direkt med en SQL Database- eller SQL Managed Instance-SELECT-instruktion som misslyckades med ett tillfälligt fel. Upprätta i stället en ny anslutning och försök sedan igen SELECT.
  • När en SQL Database- eller SQL Managed Instance-UPDATE-instruktion misslyckas med ett tillfälligt fel upprättar du en ny anslutning innan du försöker uppdatera igen. Logiken för återförsök måste se till att antingen hela databastransaktionen har slutförts eller att hela transaktionen återställs.

Andra överväganden för återförsök

  • Ett batchprogram som startar automatiskt efter arbetstid och avslutas före morgonen har råd att ha mycket tålamod med långa tidsintervall mellan försöken.
  • Ett användargränssnittsprogram bör ta hänsyn till den mänskliga tendensen att ge upp efter för lång väntan. Lösningen får inte försöka igen med några sekunders mellanrum, eftersom den principen kan översvämma systemet med begäranden.

Ökning av intervallet mellan återförsök

Vi rekommenderar att du väntar i 5 sekunder innan du försöker igen. Om du försöker igen efter en fördröjning som är kortare än 5 sekunder riskerar du att överbelasta molntjänsten. För varje efterföljande återförsök bör fördröjningen växa exponentiellt, upp till högst 60 sekunder.

En diskussion om blockeringsperioden för klienter som använder ADO.NET finns i Anslutningspool (ADO.NET).

Du kanske också vill ange ett maximalt antal återförsök innan programmet avslutas själv.

Kodexempel med logik för omförsök

Kodexempel med omprövningslogik finns på:

Testa logiken för återförsök

Om du vill testa logiken för återförsök måste du simulera eller orsaka ett fel som kan korrigeras medan programmet fortfarande körs.

Testa genom att koppla från nätverket

Ett sätt att testa logiken för återförsök är att koppla från klientdatorn från nätverket medan programmet körs. Felet är:

  • SqlException.Number = 11001
  • Meddelande: "Ingen sådan värd är känd"

Som en del av det första återförsöket kan du återansluta klientdatorn till nätverket och sedan försöka ansluta.

Om du vill göra det här testet praktiskt kan du koppla från datorn från nätverket innan du startar programmet. Sedan identifierar programmet en körningsparameter som gör att programmet:

  • Lägg tillfälligt till 11001 i listan över fel som ska anses vara tillfälliga.
  • Försök med den första anslutningen som vanligt.
  • När felet har fastnat tar du bort 11001 från listan.
  • Visa ett meddelande som uppmanar användaren att ansluta datorn till nätverket.
  • Pausa körningen ytterligare genom att använda antingen metoden Console.ReadLine eller en dialogruta med en OK-knapp. Användaren trycker på Retur-tangenten när datorn är ansluten till nätverket.
  • Försök igen att ansluta och förvänta dig att lyckas.

Testa genom att felstava användarnamnet vid anslutning

Ditt program kan avsiktligt felstava användarnamnet före det första anslutningsförsöket. Felet är:

  • SqlException.Number = 18456
  • Meddelande: "Inloggningen misslyckades för användaren 'WRONG_MyUserName'."

Som en del av det första återförsöket kan programmet korrigera felstavningen och sedan försöka ansluta.

För att göra det här testet praktiskt identifierar programmet en körningsparameter som gör att programmet:

  • Lägg tillfälligt till 18456 i listan över fel som ska anses vara tillfälliga.
  • Lägg avsiktligt till "WRONG_" i användarnamnet.
  • När felet har fastnat tar du bort 18456 från listan.
  • Ta bort "WRONG_" från användarnamnet.
  • Försök igen att ansluta och förvänta dig att lyckas.

.NET SqlConnection-parametrar för återförsök av anslutning

Om klientprogrammet ansluter till databasen i Azure SQL Database med hjälp av .NET Framework-klassen System.Data.SqlClient.SqlConnectionanvänder du .NET 4.6.1 eller en senare version (eller .NET Core) så att du kan använda funktionen för återförsök av anslutningen. Mer information om den här funktionen finns i SqlConnection.ConnectionString Property.

När du skapar anslutningssträngen för ditt SqlConnection--objekt samordnar du värdena mellan följande parametrar:

  • ConnectRetryCount: Standardvärdet är 1. Intervallet är 0 genom 255.
  • ConnectRetryInterval: Standardvärdet är 10 sekunder. Intervallet är 1 via 60.
  • Tidsgräns för anslutning: Standardvärdet är 15 sekunder. Intervallet är 0 via 2147483647.
  • Kommandotimeout: Standardvärdet är 30 sekunder. Intervallet är 0 via 2147483647.

Inställningarna för anslutningsförsök (ConnectRetryCount och ConnectRetryInterval) gäller för anslutningsåterhämtning. Anslutningsresiliens innehåller följande distinkta typer:

  • Återhämtningsförmåga för öppna anslutningar avser den inledande SqlConnection.Open- eller OpenAsync()-metoden. Det första anslutningsförsöket räknas som försök noll. ConnectRetryCount gäller för efterföljande återförsök. Om anslutning noll misslyckas (detta kanske inte inträffar omedelbart) tillämpas ConnectRetryInterval först följt av efterföljande ConnectRetryCount (och ConnectRetryInterval) försöken. Om du vill dra nytta av alla återförsök måste egenskapen timeout för anslutning ge tid för alla försök.

  • Återhämtning av inaktiva anslutningar syftar på automatisk upptäckt och återanslutning av befintliga inaktiva anslutningar som brutits. Det första försöket att återansluta en bruten inaktiv anslutning räknas som det första återförsöket. Om du vill dra nytta av alla återförsök måste -kommandots tidsgräns ge tid för alla försök.

Exempel: Anta följande värden för parametrarna ConnectRetryCount och ConnectRetryInterval:

ConnectRetryCount: 3 ConnectRetryInterval: 10 sekunder

Se hur dessa värden används i följande scenarier:

scenario: Ny anslutning

4:10:00 – Connection.Open() – noll försök

4:10:01 – Anslutningsfel har identifierats

4:10:11 – Försök igen 1 –> Första återförsöket görs efter ConnectRetryInterval

4:10:21 – Försök igen 2

4:10:31 – Försök igen 3

I det här scenariot bör dina valda värden uppfylla följande villkor:
Connection Timeout > = ConnectRetryCount * ConnectionRetryInterval

Om antalet till exempel är 3 och intervallet är 10 sekunder ger en tidsgräns på bara 29 sekunder inte tillräckligt med tid för systemets tredje och sista återförsök att ansluta:

29 < 3 * 10

scenario: Inaktiv anslutning

ConnectRetryCount: 3 ConnectRetryInterval: 10 sekunder

4:10:00 – Bruten anslutning identifierad vid kommandokörning

4:10:00 – Försök igen 1 –>Första återförsöket görs omedelbart

4:10:10 – Försök igen 2

4:10:20 – Försök igen 3

Det här är inte den första anslutningen. Därför gäller inte anslutningstidsgränsen . Men eftersom anslutningsåterställningen sker under kommandokörningen gäller inställningen timeout för kommando. Tidsgränsen för -kommandot är som standard 30 sekunder. Även om anslutningsåterställningen är snabb under normala omständigheter kan ett tillfälligt avbrott leda till att återställningen tar en del av kommandots exekveringstid.

För det här scenariot, om du vill dra full nytta av återställningsförsök för inaktiv anslutning, bör dina valda värden uppfylla följande villkor:
Command Timeout > (ConnectRetryCount - 1) * ConnectionRetryInterval

Om antalet till exempel är 3 och intervallet är 10 sekunder skulle ett timeoutvärde för kommandon som är lägre än 20 sekunder inte ge tillräckligt med tid för det tredje och sista återförsöket att ansluta: (3–1) * 10 = 20'

Tänk också på att själva kommandot kräver tid att köra när anslutningen har återställts.

Anmärkning

Varaktighetsvärdena som anges i dessa scenarier är endast för demonstration. De faktiska identifieringstiderna i båda scenarierna beror på den underliggande infrastrukturen.

Anslutning mot kommando

Parametrarna ConnectRetryCount och ConnectRetryInterval gör att ditt SqlConnection- objekt kan försöka ansluta igen utan att berätta eller störa ditt program, till exempel att returnera kontroll till programmet. Återförsöken kan inträffa i följande situationer:

  • SqlConnection.Open method call
  • SqlConnection-Execute-metodanrop

Det finns en subtilitet. Om ett tillfälligt fel inträffar när din fråga körs försöker inte ditt SqlConnection--objekt ansluta igen. Systemet försöker inte din förfrågan igen. Men SqlConnection kontrollerar mycket snabbt anslutningen innan du skickar frågan för utförande. Om snabbkontrollen identifierar ett anslutningsproblem SqlConnection försöker ansluta igen. Om återförsöket lyckas skickas frågan för körning.

Ska ConnectRetryCount kombineras med logik för omprövning av program

Anta att ditt program har robust logik för anpassade återförsök. Den kan försöka ansluta igen fyra gånger. Om du lägger till ConnectRetryInterval och ConnectRetryCount =3 i anslutningssträngen ökar du antalet återförsök till 4 * 3 = 12 återförsök. Du kanske inte har för avsikt att göra så många återförsök.

Anslutningar till databasen i SQL Database

Anslutning: Anslutningssträng

Anslutningssträngen som krävs för att ansluta till databasen skiljer sig något från strängen som används för att ansluta till SQL Server. Du kan kopiera anslutningssträngen för databasen från Azure-portalen.

Hämta anslutningssträngen från Azure-portalen

Använd Azure-portalen för att hämta anslutningssträngen som krävs för att klientprogrammet ska kunna interagera med Azure SQL Database.

  1. Välj Alla tjänster>SQL-databaser.

  2. Ange namnet på databasen i filtertextrutan längst upp till vänster i fönstret SQL-databaser.

  3. Välj raden för din databas.

  4. När fönstret för databasen visas, välj för ökad översikt knapparna Minimera för att fälla ihop de paneler du använde för bläddring och databasfiltrering.

  5. I fönstret för databasen väljer du Visa databasanslutningssträngar.

  6. Kopiera lämplig anslutningssträng. Om du till exempel tänker använda anslutningsbiblioteket ADO.NET kopierar du lämplig sträng från fliken ADO.NET.

    Skärmbild som visar hur du kopierar ADO-anslutningssträngen för databasen.

  7. Redigera anslutningssträngen efter behov. I det här exemplet infogar du lösenordet i anslutningssträngen eller tar bort <server-name> från användarnamnet om användarnamnet eller servernamnet är för långt.

  8. I ett eller annat format klistrar du in informationen om anslutningssträngen i klientprogramkoden.

Mer information finns i Anslutningssträngar och konfigurationsfiler.

Anslutning: IP-adress

Du måste konfigurera SQL Database för att acceptera kommunikation från IP-adressen för den dator som är värd för klientprogrammet. Om du vill konfigurera den här konfigurationen redigerar du brandväggsinställningarna via Azure-portalen.

Om du glömmer att konfigurera IP-adressen misslyckas programmet med ett praktiskt felmeddelande som anger den nödvändiga IP-adressen.

  1. Logga in på Azure-portalen.

  2. I listan till vänster väljer du Alla tjänster.

  3. Rulla och välj SQL-servrar.

    Skärmbild av Hitta din Azure SQL Database-server i portalen.

  4. I textrutan filter börjar du skriva namnet på servern. Din rad visas.

  5. Välj raden för din server. En fönsterruta för servern visas.

  6. I serverfönstret väljer du Inställningar.

  7. Välj Firewall.

    skärmbild av Välj inställningar > brandvägg.

  8. Välj Lägg till klient-IP-. Skriv ett namn på den nya regeln i den första textrutan.

  9. Ange de låga och höga IP-adressvärdena för det intervall som du vill aktivera.

    • Det kan vara praktiskt att låta det låga värdet sluta med .0 och det höga värdet sluta med .255.
  10. Välj Spara.

Mer information finns i Konfigurera brandväggsinställningar i SQL Database.

Anslutning: Portar

Vanligtvis måste du se till att endast port 1433 är öppen för utgående kommunikation på den dator som är värd för klientprogrammet.

När ditt klientprogram till exempel finns på en Windows-dator kan du använda Windows-brandväggen på värddatorn för att öppna port 1433.

  1. Öppna Kontrollpanelen.
  2. Välj Alla kontrollpanelsobjekt>Windows-brandväggen>Avancerade inställningar>utgående regler>åtgärder>ny regel.

Om ditt klientprogram finns på en virtuell Azure-maskin, läs Portar utöver 1433 för ADO.NET 4.5 och SQL Database.

Bakgrundsinformation om konfiguration av portar och IP-adresser i databasen finns i Azure SQL Database-brandväggen.

Anslutning: ADO.NET 4.6.2 eller senare

Om ditt program använder ADO.NET klasser som System.Data.SqlClient.SqlConnection för att ansluta till SQL Database rekommenderar vi att du använder .NET Framework version 4.6.2 eller senare.

Börjar med ADO.NET 4.6.2

  • Ett nytt försök att öppna anslutningen görs omedelbart för Azure SQL, vilket förbättrar prestandan för appar med molnstöd.

Börjar med ADO.NET 4.6.1

  • För SQL Database förbättras tillförlitligheten när du öppnar en anslutning med hjälp av metoden SqlConnection.Open. Metoden Open innehåller nu återförsöksmekanismer med bästa möjliga insats som svar på tillfälliga fel vid vissa fel inom anslutningens timeout-period.
  • Anslutningspooler stöds, vilket innefattar en effektiv verifiering av att anslutningsobjektet som det ger programmet fungerar.

När du använder ett anslutningsobjekt från en anslutningspool rekommenderar vi att programmet tillfälligt stänger anslutningen när den inte används omedelbart. Det är inte dyrt att öppna en anslutning igen, men det är att skapa en ny anslutning.

Om du använder ADO.NET 4.0 eller tidigare rekommenderar vi att du uppgraderar till den senaste ADO.NET. Från och med augusti 2018 kan du ladda ned ADO.NET 4.6.2.

Diagnostik

Diagnostik: Testa om verktyg kan ansluta

Om programmet inte kan ansluta till databasen i SQL Database är ett diagnostikalternativ att försöka ansluta till ett verktygsprogram. Helst ansluter verktyget med hjälp av samma bibliotek som programmet använder.

På valfri Windows-dator kan du prova dessa verktyg:

  • SQL Server Management Studio (ssms.exe), som ansluter med hjälp av ADO.NET
  • sqlcmd.exe, som ansluter med hjälp av ODBC-

När programmet har anslutits testar du om en kort SQL SELECT-fråga fungerar.

Diagnostik: Kontrollera de öppna portarna

Om du misstänker att anslutningsförsök misslyckas på grund av portproblem kan du köra ett verktyg på datorn som rapporterar om portkonfigurationerna.

I Linux kan följande verktyg vara till hjälp:

  • netstat -nap
  • nmap -sS -O 127.0.0.1: Ändra exempelvärdet till din IP-adress.

I Windows kan verktyget PortQry.exe vara användbart. Här är ett exempel på en körning som efterfrågade portsituationen på en databas i SQL Database och som kördes på en bärbar dator:

[C:\Users\johndoe\]
>> portqry.exe -n johndoesvr9.database.windows.net -p tcp -e 1433

Querying target system called: johndoesvr9.database.windows.net

Attempting to resolve name to IP address...
Name resolved to 23.100.117.95

querying...
TCP port 1433 (ms-sql-s service): LISTENING

[C:\Users\johndoe\]
>>

Diagnostik: Logga dina fel

Ett tillfälligt problem diagnostiseras ibland bäst genom identifiering av ett allmänt mönster över dagar eller veckor.

Klienten kan hjälpa till med en diagnos genom att logga alla fel som den stöter på. Du kanske kan korrelera loggposterna med feldata som SQL Database loggar internt.

Företagsbibliotek 6 (EntLib60) erbjuder .NET-hanterade klasser för att hjälpa till med loggning. Mer information finns i 5 – Lika enkelt som en plätt: Använd loggningsprogrammet.

Diagnostik: Undersök systemloggar efter fel

Här följer några Transact-SQL SELECT-instruktioner som frågar efter felloggar och annan information.

Logguppslag Beskrivning
SELECT e.*
FROM sys.event_log AS e
WHERE e.database_name = 'myDbName'
AND e.event_category = 'connectivity'
AND 2 >= DateDiff
  (hour, e.end_time, GetUtcDate())
ORDER BY e.event_category,
  e.event_type, e.end_time;
Vyn sys.event_log innehåller information om enskilda händelser, som innehåller några som kan orsaka tillfälliga fel eller anslutningsfel.

Helst kan du korrelera start_time eller end_time värden med information om när klientprogrammet har haft problem.

Du måste ansluta till huvuddatabasen för att utföra den här sökfrågan.
SELECT c.*
FROM sys.database_connection_stats AS c
WHERE c.database_name = 'myDbName'
AND 24 >= DateDiff
  (hour, c.end_time, GetUtcDate())
ORDER BY c.end_time;
Vyn sys.database_connection_stats erbjuder aggregerade antal händelsetyper för ytterligare diagnostik.

Du måste ansluta till huvuddatabasen för att köra den här fråge.

Diagnostik: Sök efter problemhändelser i SQL Database-loggen

Du kan söka efter poster om problemhändelser i SQL Database-loggen. Prova följande Transact-SQL SELECT-instruktion i huvuddatabasen:

SELECT
   object_name
  ,CAST(f.event_data as XML).value
      ('(/event/@timestamp)[1]', 'datetime2')                      AS [timestamp]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="error"]/value)[1]', 'int')             AS [error]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="state"]/value)[1]', 'int')             AS [state]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="is_success"]/value)[1]', 'bit')        AS [is_success]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="database_name"]/value)[1]', 'sysname') AS [database_name]
FROM
  sys.fn_xe_telemetry_blob_target_read_file('el', null, null, null) AS f
WHERE
  object_name != 'login_event'  -- Login events are numerous.
  and
  '2015-06-21' < CAST(f.event_data as XML).value
        ('(/event/@timestamp)[1]', 'datetime2')
ORDER BY
  [timestamp] DESC
;

Några returnerade rader från sys.fn_xe_telemetry_blob_target_read_file

I följande exempel visas hur en returnerad rad kan se ut. De null-värden som visas är ofta inte null i andra rader.

object_name                   timestamp                    error  state  is_success  database_name

database_xml_deadlock_report  2015-10-16 20:28:01.0090000  NULL   NULL   NULL        AdventureWorks

Företagsbibliotek 6

Enterprise Library 6 (EntLib60) är ett ramverk av .NET-klasser som hjälper dig att implementera robusta klienter för molntjänster, varav en är SQL Database. Information om hur du hittar ämnen som är dedikerade till varje område där EntLib60 kan hjälpa till finns i Företagsbibliotek 6.

Omprövningslogik för hantering av tillfälliga fel är ett område där EntLib60 kan hjälpa till. Mer information finns i 4 – Uthållighet, hemlighet för alla triumfer: Använd programblocket för övergående felhantering.

Not

Källkoden för EntLib60 är tillgänglig för offentlig nedladdning från Download Center. Microsoft har inga planer på att göra ytterligare funktionsuppdateringar eller underhållsuppdateringar till EntLib.

EntLib60-klasser för tillfälliga fel och försök igen

Följande EntLib60-klasser är särskilt användbara för omprövningslogik. Alla dessa klasser finns i eller under namnområdet Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.

I namnområdet Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling:

  • RetryPolicy-klass
    • ExecuteAction-metod
  • ExponentialBackoff-klass
  • SqlDatabaseTransientErrorDetectionStrategy-klass
  • ReliableSqlConnection-klass
    • ExecuteCommand-metod

I namnområdet Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.TestSupport:

  • AlwaysTransientErrorDetectionStrategy-klass
  • NeverTransientErrorDetectionStrategy-klass

Här följer några länkar till information om EntLib60:

EntLib60: Loggningsblocket

  • Loggningsblocket är en mycket flexibel och konfigurerbar lösning som du kan använda för att:
    • Skapa och lagra loggmeddelanden på en mängd olika platser.
    • Kategorisera och filtrera meddelanden.
    • Samla in sammanhangsbaserad information som är användbar för felsökning och spårning, samt för granskning och allmänna loggningskrav.
  • Loggningsblocket abstraherar loggningsfunktionen från loggmålet så att programkoden är konsekvent, oavsett plats och typ av målloggningsarkiv.

Mer information finns i 5 – Lika enkelt som en plätt: Använd loggningsprogrammodulen.

Källkod för EntLib60 IsTransient-metod

Sedan, från klassen SqlDatabaseTransientErrorDetectionStrategy, är C#-källkoden för metoden IsTransient. Källkoden klargör vilka fel som ansågs vara tillfälliga och värda att försöka igen.

public bool IsTransient(Exception ex)
{
  if (ex != null)
  {
    SqlException sqlException;
    if ((sqlException = ex as SqlException) != null)
    {
      // Enumerate through all errors found in the exception.
      foreach (SqlError err in sqlException.Errors)
      {
        switch (err.Number)
        {
            // SQL Error Code: 40501
            // The service is currently busy. Retry the request after 10 seconds.
            // Code: (reason code to be decoded).
          case ThrottlingCondition.ThrottlingErrorNumber:
            // Decode the reason code from the error message to
            // determine the grounds for throttling.
            var condition = ThrottlingCondition.FromError(err);

            // Attach the decoded values as additional attributes to
            // the original SQL exception.
            sqlException.Data[condition.ThrottlingMode.GetType().Name] =
              condition.ThrottlingMode.ToString();
            sqlException.Data[condition.GetType().Name] = condition;

            return true;

          case 10928:
          case 10929:
          case 10053:
          case 10054:
          case 10060:
          case 40197:
          case 40540:
          case 40613:
          case 40143:
          case 233:
          case 64:
            // DBNETLIB Error Code: 20
            // The instance of SQL Server you attempted to connect to
            // does not support encryption.
          case (int)ProcessNetLibErrorCode.EncryptionNotSupported:
            return true;
        }
      }
    }
    else if (ex is TimeoutException)
    {
      return true;
    }
    else
    {
      EntityException entityException;
      if ((entityException = ex as EntityException) != null)
      {
        return this.IsTransient(entityException.InnerException);
      }
    }
  }

  return false;
}

Nästa steg