Anteckning
Å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 innehåller ett C#-kodexempel som visar anpassad logik för återförsök. Logiken för återförsök ger tillförlitlighet. Logiken för återförsök är utformad för att korrekt bearbeta tillfälliga fel eller tillfälliga fel som tenderar att försvinna om programmet väntar flera sekunder och försöker igen.
Källor till tillfälliga fel är:
- Ett kort fel i nätverket som stöder Internet.
- Ett molnsystem kan vara upptagen med att belastningsutjämna sina resurser vid den tidpunkt då din fråga skickades.
De ADO.NET klasserna för anslutning till din lokala Microsoft SQL Server kan också ansluta till Azure SQL Database. De ADO.NET klasserna kan dock inte ge all robusthet och tillförlitlighet som krävs i produktionsanvändningen. Klientprogrammet kan stöta på tillfälliga fel från vilka det ska återhämta sig utan att märkas och på ett smidigt sätt fortsätta på egen hand.
Steg 1: Identifiera tillfälliga fel
Programmet måste skilja mellan tillfälliga fel och beständiga fel. Tillfälliga fel är feltillstånd som kan rensas inom en kort tidsperiod, till exempel tillfälliga nätverksproblem. Ett exempel på ett beständigt fel skulle vara om programmet har felstavat måldatabasnamnet. I det här fallet skulle felet "Ingen sådan databas hittades" bestå och har ingen chans att rensa upp inom en kort tidsperiod.
Listan över felnummer som kategoriseras som tillfälliga fel finns i Felmeddelanden för SQL Database-klientprogram
Steg 2: Skapa och köra exempelprogram
Det här exemplet förutsätter att .NET Framework 4.6.2 eller senare installeras. C#-kodexemplet består av en fil med namnet 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.
- Fil > Nytt projekt > Projekt > Installerade > Mallar > Visual C# > Windows > Klassisk skrivbordskonsolapplikation >
- Ge projektet namnet RetryAdo2.
- Öppna fönstret Solution Explorer.
- Se namnet på projektet.
- I projektet lägger du till ett NuGet-beroende för Microsoft.Data.SqlClient-paketet.
- Se namnet på Program.cs-filen.
- Öppna filen Program.cs.
- Ersätt innehållet i Program.cs-filen helt med koden i följande kodblock.
- Välj menyn Skapa > bygglösning.
Steg 2.b: Kopiera och klistra in exempelkod
Klistra in den här koden i din Program.cs-fil .
Sedan måste du redigera strängarna för servernamn, lösenord och så vidare. Du hittar dessa strängar i metoden GetSqlConnectionString.
Anmärkning
Anslutningssträngen för servernamnet är inriktad på Azure SQL Database eftersom den innehåller prefixet tcp:. Men du kan justera serversträngen för att ansluta till Din Microsoft SQL Server.
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
Den körbara filen RetryAdo2.exe tar inga parametrar. Så här kör du .exe:
- Öppna ett konsolfönster där du har kompilerat RetryAdo2.exe binärfil.
- Kör RetryAdo2.exe, utan indataparametrar.
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
Det finns en mängd olika sätt att simulera ett tillfälligt fel för att testa logiken för återförsök.
Steg 3.a: Utlöser ett testundantag
Kodexemplet innehåller:
- En liten andra klass med namnet TestSqlException, med egenskapen Number.
-
//throw new TestSqlException(4060);, som du kan avkommenta.
Om du avkommenterar throw-instruktionen och kompilera om, matar nästa körning av RetryAdo2.exe ut något som liknar 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
Om du vill bevisa att koden hanterar beständiga fel korrekt kör du föregående test igen, förutom att inte använda antalet verkliga tillfälliga fel som 4060. Använd i stället nonsensnumret 7654321. Programmet bör behandla detta som ett beständigt fel och bör kringgå eventuella återfö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.exeoch vänta tills konsolen visar det första tillfälliga felet, förmodligen 11001.
- Återanslut till nätverket medan RetryAdo2.exe fortsä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 i 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.