Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
- Föregående artikel: Steg 3: Proof of Concept som ansluter till SQL med hjälp av ADO.NET
Den här artikeln ger ett C#-kodexempel som demonstrerar manuellt implementerad retry-logik. Omprovningslogiken hanterar tillfälliga fel, eller tillfälliga fel, som kan försvinna om programmet väntar och försöker operationen igen.
Viktigt!
För nya applikationer som använder Microsoft.Data.SqlClient 3.0 och senare versioner bör ni i första hand använda drivrutinens konfigurerbara försökslogik i stället för att implementera en omförsöksslinga. Börja med Konfigurera återförsökslogik i SqlClient.
Källor till tillfälliga fel är:
- Ett kortvarigt fel i nätverket som stöder internet.
- Ett molnsystem kan lastbalansera sina resurser när din förfrågan anländer.
ADO.NET-klasserna för anslutning till SQL Server kan också kopplas till Azure SQL Database. Ditt klientprogram kan stöta på övergående fel. Den bör återhämta sig genom att använda en begränsad återförsökspolicy som är lämplig för operationen.
Steg 1: Identifiera tillfälliga fel
Ditt program måste skilja mellan övergående fel och beständiga fel. Tillfälliga fel är felförhållanden som kan försvinna på kort tid, såsom tillfälliga nätverksproblem. Ett exempel på ett bestående fel är en felstavning av namnet på måldatabasen. I så fall kvarstår felet "No such database found" och försvinner inte snabbt.
Listan över felnummer som kategoriseras som tillfälliga fel finns tillgänglig på Felmeddelanden för SQL Database-klientapplikationer.
Steg 2: Skapa och köra exempelprogram
Det här exemplet förutsätter att .NET Framework 4.6.2 eller senare installeras. C#-kodprovet består av en fil som heter Program.cs. Koden finns i nästa avsnitt.
Steg 2.a: Samla in och kompilera kodexemplet
Du kan kompilera exemplet med följande steg:
I den kostnadsfria Visual Studio Community-utgåvan skapar du ett nytt projekt från C#-konsolprogrammallen.
Välj Fil>Nytt>Projekt>Installerade>Mallar>Visual C#>Windows>Klassiskt skrivbord>Konsolprogram.
Ge projektet namnet
RetryAdo2.
Öppna fönstret Prieskumník riešení.
- Se namnet på projektet.
- I projektet lägger du till ett NuGet-beroende för Microsoft.Data.SqlClient-paketet.
- Visa namnet på filen
Program.cs.
Öppna
Program.cs-filen.Ersätt hela innehållet i
Program.csfilen med koden i följande kodblock.Välj menyn Bygg>Bygg Lösning.
Steg 2.b: Kopiera och klistra in exempelkod
Klistra in denna kod i din Program.cs fil.
Redigera sedan strängarna för serverns namn och lösenord. Du kan hitta dessa strängar i metoden som heter GetSqlConnectionString.
Anmärkning
reťazec pripojenia är inriktad på Azure SQL Database, eftersom den inkluderar det fyrteckensprefixet tcp:. Men du kan justera serversträngen för att ansluta till din SQL Server-instans.
using System;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using System.Threading;
namespace RetryAdo2;
public class Program
{
public static int Main(string[] args)
{
bool succeeded = false;
const int totalNumberOfTimesToTry = 4;
int retryIntervalSeconds = 10;
for (int tries = 1; tries <= totalNumberOfTimesToTry; tries++)
{
try
{
if (tries > 1)
{
Console.WriteLine(
"Transient error encountered. Will begin attempt number {0} of {1} max...",
tries,
totalNumberOfTimesToTry
);
Thread.Sleep(1000 * retryIntervalSeconds);
retryIntervalSeconds = Convert.ToInt32(retryIntervalSeconds * 1.5);
}
AccessDatabase();
succeeded = true;
break;
}
catch (SqlException sqlExc) {
if (TransientErrorNumbers.Contains(sqlExc.Number))
{
Console.WriteLine("{0}: transient occurred.", sqlExc.Number);
continue;
}
Console.WriteLine(sqlExc);
break;
}
catch (TestSqlException sqlExc) {
if (TransientErrorNumbers.Contains(sqlExc.Number))
{
Console.WriteLine("{0}: transient occurred. (TESTING.)", sqlExc.Number);
continue;
}
Console.WriteLine(sqlExc);
break;
}
catch (Exception e)
{
Console.WriteLine(e);
break;
}
}
if (!succeeded) {
Console.WriteLine("ERROR: Unable to access the database!");
return 1;
}
return 0;
}
/// <summary>
/// Connects to the database, reads,
/// prints results to the console.
/// </summary>
static void AccessDatabase() {
//throw new TestSqlException(4060); //(7654321); // Uncomment for testing.
using var sqlConnection = new SqlConnection(GetSqlConnectionString());
using var dbCommand = sqlConnection.CreateCommand();
dbCommand.CommandText = @"
SELECT TOP 3
ob.name,
CAST(ob.object_id as NVARCHAR(32)) AS [object_id]
FROM sys.objects AS ob
WHERE ob.type='IT'
ORDER BY ob.name;";
sqlConnection.Open();
var dataReader = dbCommand.ExecuteReader();
while (dataReader.Read())
{
Console.WriteLine(
"{0}\t{1}",
dataReader.GetString(0),
dataReader.GetString(1)
);
}
}
/// <summary>
/// Edit the four string values in accordance with your environment.
/// </summary>
/// <returns>An ADO.NET connection string.</returns>
static private string GetSqlConnectionString()
{
// Prepare the connection string to Azure SQL Database.
var sqlConnectionSB = new SqlConnectionStringBuilder
{
// Change these values to your values.
DataSource = "tcp:myazuresqldbserver.database.windows.net,1433", //["Server"]
InitialCatalog = "MyDatabase", //["Database"]
UserID = "MyLogin", // "@yourservername" as suffix sometimes.
Password = "<password>",
// Adjust these values if you like. (ADO.NET 4.5.1 or later.)
ConnectRetryCount = 3,
ConnectRetryInterval = 10, // Seconds.
// Leave these values as they are.
IntegratedSecurity = false,
Encrypt = true,
ConnectTimeout = 30
};
return sqlConnectionSB.ToString();
}
static List<int> TransientErrorNumbers = new()
{
4060, 40197, 40501, 40613, 49918, 49919, 49920, 11001
};
}
/// <summary>
/// For testing retry logic, you can have method
/// AccessDatabase start by throwing a new
/// TestSqlException with a Number that does
/// or does not match a transient error number
/// present in TransientErrorNumbers.
/// </summary>
internal class TestSqlException : ApplicationException
{
internal TestSqlException(int testErrorNumber)
{
Number = testErrorNumber;
}
internal int Number { get; set; }
}
Steg 2.c: Kör programmet
RetryAdo2.exe-programmet accepterar inte parametrar. För att köra .exe:
- Öppna ett konsolfönster i mappen där du kompilerade binärfilen
RetryAdo2.exe. - Kör
RetryAdo2.exeutan inmatningsparametrar.
database_firewall_rules_table 245575913
filestream_tombstone_2073058421 2073058421
filetable_updates_2105058535 2105058535
Steg 3: Sätt att testa logiken för återförsök
Du kan simulera ett transient fel för att testa din retry-logik på flera sätt.
Steg 3.a: Utlöser ett testundantag
Kodexemplet innehåller:
- En liten sekundär klass med namnet
TestSqlExceptionoch en egenskap med namnetNumber. -
//throw new TestSqlException(4060);, som du kan avkommenta.
Om du avkommenterar throw-satsen och kompilerar om, kommer nästa körning av RetryAdo2.exe att ge något i stil med följande.
[C:\VS15\RetryAdo2\RetryAdo2\bin\Debug\]
>> RetryAdo2.exe
4060: transient occurred. (TESTING.)
Transient error encountered. Will begin attempt number 2 of 4 max...
4060: transient occurred. (TESTING.)
Transient error encountered. Will begin attempt number 3 of 4 max...
4060: transient occurred. (TESTING.)
Transient error encountered. Will begin attempt number 4 of 4 max...
4060: transient occurred. (TESTING.)
ERROR: Unable to access the database!
[C:\VS15\RetryAdo2\RetryAdo2\bin\Debug\]
>>
Steg 3.b: Testa igen med ett beständigt fel
För att bevisa att koden hanterar persistenta fel korrekt, kör det föregående testet igen. Istället för att använda ett verkligt övergående felnummer som 4060, använd det fiktiva numret 7654321. Programmet behandlar detta nummer som ett bestående fel och kringgår alla omförsök.
Steg 3.c: Koppla från nätverket
- Koppla från klientdatorn från nätverket.
- Koppla bort nätverkskabeln från en stationär dator.
- För en bärbar dator trycker du på funktionskombinationen av nycklar för att stänga av nätverkskortet.
- Starta
RetryAdo2.exe, och vänta på att konsolen visar det första övergående felet, troligen 11001. - Återanslut till nätverket, medan
RetryAdo2.exefortsätter att köras. - Se hur konsolrapporten lyckades vid ett efterföljande återförsök.
Steg 3.d: Tillfälligt felstava servernamnet
- Lägg tillfälligt till 40615 som ett annat felnummer till
TransientErrorNumbers, och kompilera om. - Ange en brytpunkt på raden:
new QC.SqlConnectionStringBuilder(). - Använd funktionen Redigera och fortsätt för att avsiktligt felstava servernamnet, ett par rader nedan.
- Låt programmet köras och komma tillbaka till brytpunkten.
- Felet 40615 inträffar.
- Åtgärda felstavningen.
- Låt programmet köras och slutföras framgångsrikt.
- Ta bort 40615 och kompilera om.