Ereignisse
31. März, 23 Uhr - 2. Apr., 23 Uhr
Das größte SQL-, Fabric- und Power BI-Lernereignis. 31. März – 2. April. Verwenden Sie Code FABINSIDER, um $400 zu sparen.
Jetzt registrierenDieser Browser wird nicht mehr unterstützt.
Führen Sie ein Upgrade auf Microsoft Edge durch, um die neuesten Features, Sicherheitsupdates und den technischen Support zu nutzen.
Dieses Thema enthält ein C#-Codebeispiel zur Veranschaulichung einer benutzerdefinierten Wiederholungslogik. Die Wiederholungslogik sorgt für Zuverlässigkeit. Die Wiederholungslogik dient zum ordnungsgemäßen Verarbeiten von vorübergehenden Fehlern, die meist nicht mehr vorhanden sind, wenn das Programm mehrere Sekunden wartet und es dann erneut versucht.
Quellen vorübergehender Fehler sind u. a.:
ADO.NET-Klassen für die Verbindung mit Ihrem lokalen Microsoft SQL Server können auch Verbindungen mit Azure SQL-Datenbanken herstellen. Allerdings können die ADO.NET-Klassen allein nicht die ganze Stabilität und Zuverlässigkeit bieten, die für den Produktionseinsatz erforderlich sind. Ihr Clientprogramm kann auf vorübergehende Fehler stoßen, von denen es sich ohne Benutzereingriff ordnungsgemäß erholen sollte, um anschließend selbständig weiterzuarbeiten.
Ihr Programm muss zwischen vorübergehenden Fehlern und beständigen Fehlern unterscheiden. Vorübergehende Fehler sind Fehlerbedingungen, die sich innerhalb kurzer Zeit auflösen können, wie z. B. zeitweilige Netzwerkprobleme. Ein Beispiel eines dauerhaften Fehlers wäre, wenn in Ihrem Programm ein Schreibfehler im Namen der Zieldatenbank vorliegt. In diesem Fall würde der Fehler "Keine solche Datenbank gefunden" bestehen bleiben und keine Chance haben, sich innerhalb kurzer Zeit zu korrigieren.
Die Liste der Fehlernummern, die als vorübergehende Fehler kategorisiert sind, finden Sie unter Fehlermeldungen für SQL-Datenbank-Clientanwendungen.
Bei dem Beispiel wird davon ausgegangen, dass .NET Framework 4.6.2 oder höher installiert ist. Das C#-Codebeispiel besteht aus einer Datei mit dem Namen "Program.cs". Den Code dazu finden Sie im nächsten Abschnitt.
Sie können das Beispiel mit den folgenden Schritten kompilieren:
Fügen Sie diesen Code in die Datei Program.cs ein.
Anschließend müssen Sie die Zeichenfolgen für Servername, Kennwort usw. bearbeiten. Sie finden diese Zeichenfolgen in der Methode namens GetSqlConnectionString.
HINWEIS: Die Verbindungszeichenfolge für den Servernamen ist auf Azure SQL-Datenbank ausgerichtet, da sie das vier Zeichen lange Präfix tcp: enthält. Sie können jedoch die Serverzeichenfolge für die Verbindung mit Ihrer Microsoft SQL Server-Instanz anpassen.
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);
succeeded = false;
break;
}
catch (TestSqlException sqlExc) {
if (TransientErrorNumbers.Contains(sqlExc.Number))
{
Console.WriteLine("{0}: transient occurred. (TESTING.)", sqlExc.Number);
continue;
}
Console.WriteLine(sqlExc);
succeeded = false;
break;
}
catch (Exception e)
{
Console.WriteLine(e);
succeeded = false;
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>
/// You must edit the four 'my' string values.
/// </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 = "MyPassword",
// 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; }
}
Die ausführbare Datei RetryAdo2.exe gibt keine Parameter ein. So führen Sie die EXE-Datei aus:
database_firewall_rules_table 245575913
filestream_tombstone_2073058421 2073058421
filetable_updates_2105058535 2105058535
Es gibt verschiedene Wege, wie Sie einen vorübergehenden Fehler simulieren können, um Ihre Wiederholungslogik zu testen.
Das Codebeispiel beinhaltet:
//throw new TestSqlException(4060);
, wofür Sie die Auskommentierung aufheben können.Falls Sie die Auskommentierung für die Auslösungsanweisung aufheben und neu kompilieren, gibt die nächste Ausführung von RetryAdo2.exe etwas aus, was dem Folgenden ähnelt.
[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\]
>>
Um zu beweisen, dass der Code dauerhafte Fehler ordnungsgemäß behandelt, führen Sie den vorigen Test erneut durch, wobei Sie jedoch nicht die Nummer eines echten vorübergehenden Fehlers wie 4060 verwenden dürfen. Verwenden Sie stattdessen die unsinnige Nummer 7654321. Das Programm sollte diesen als dauerhaften Fehler behandeln und jede Wiederholung ausschließen.
new QC.SqlConnectionStringBuilder()
.Informationen zu anderen bewährten Methoden und Entwurfsrichtlinien finden Sie unter Verbindungsherstellung mit SQL-Datenbank: Links, bewährte Methoden und Entwurfsrichtlinien
Ereignisse
31. März, 23 Uhr - 2. Apr., 23 Uhr
Das größte SQL-, Fabric- und Power BI-Lernereignis. 31. März – 2. April. Verwenden Sie Code FABINSIDER, um $400 zu sparen.
Jetzt registrieren