Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez a cikk egy C#-kódmintát tartalmaz, amely bemutatja az egyéni újrapróbálkozások logikáját. Az újrapróbálkozás logikája megbízhatóságot biztosít. Az újrapróbálkozási logika úgy lett kialakítva, hogy elegánsan dolgozza fel az átmeneti hibákat vagy átmeneti hibákat, amelyek általában eltűnnek, ha a program több másodpercet vár, és újra próbálkozik.
Az átmeneti hibák forrásai a következők:
- Az internetet támogató hálózat rövid meghibásodása.
- Előfordulhat, hogy egy felhőrendszer terheléselosztást végzett az erőforrásaival a lekérdezés elküldésekor.
A helyi Microsoft SQL Serverhez való csatlakozáshoz szükséges ADO.NET osztályok is csatlakozhatnak az Azure SQL Database-hez. A ADO.NET osztályok azonban önmagukban nem képesek biztosítani az éles használathoz szükséges robusztusságot és megbízhatóságot. Az ügyfélprogram átmeneti hibákba ütközhet, amelyekből észrevétlenül és zökkenőmentesen kell helyreállnia, hogy önállóan folytathassa a működést.
1. lépés: Átmeneti hibák azonosítása
A programnak különbséget kell tennie az átmeneti hibák és az állandó hibák között. Az átmeneti hibák olyan hibafeltételek, amelyek rövid időn belül kiürülhetnek, például átmeneti hálózati problémák. Egy állandó hiba például az lehet, ha a program hibásan írja le a céladatbázis nevét – ebben az esetben a "Nem található ilyen adatbázis" hiba megmarad, és nincs esélye arra, hogy rövid időn belül törölje az adatbázist.
Az átmeneti hibaként kategorizált hibaszámok listája SQL Database-ügyfélalkalmazások hibaüzenetei
2. lépés: Mintaalkalmazás létrehozása és futtatása
Ez a minta feltételezi, hogy a .NET-keretrendszer 4.6.2-s vagy újabb verziója telepítve van. A C#-kódminta egy Program.cs nevű fájlból áll. A kód a következő szakaszban lesz megadva.
2.a. lépés: A kódminta rögzítése és fordítása
A mintát a következő lépésekkel állíthatja össze:
- Az ingyenes Visual Studio Community kiadás segítségével hozzon létre egy új projektet a C# konzolalkalmazás sablonjából.
- Fájl > Új > Projekt > Telepített > Sablonok > Visual C# > Windows > Klasszikus asztali > Konzolalkalmazás
- Nevezze el a projektet RetryAdo2.
- Nyissa meg a Megoldáskezelő panelt.
- Tekintse meg a projekt nevét.
- A projektedhez adj hozzá egy NuGet-függőséget az Microsoft.Data.SqlClient csomaghoz.
- Lásd a Program.cs fájl nevét.
- Nyissa meg a Program.cs fájlt.
- Teljes mértékben cserélje le a Program.cs fájl tartalmát a következő kódblokkban lévő kódra.
- Válassza a Build > Build Solution menüpontot.
2.b. lépés: Mintakód másolása és beillesztése
Ezt a kódot illessze be a Program.cs fájlba.
Ezután szerkesztenie kell a kiszolgáló nevének, jelszavának stb. sztringeit. Ezeket a sztringeket a GetSqlConnectionStringnevű metódusban találja.
Jegyzet
Az Azure SQL Database-re vonatkozóan a csatlakozási karakterlánc igazodik a kiszolgáló nevéhez, mivel a tcp négyszótagos előtagját tartalmazza:. A kiszolgálói sztringet azonban módosíthatja a Microsoft SQL Serverhez való csatlakozáshoz.
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; }
}
2.c. lépés: A program futtatása
A RetryAdo2.exe végrehajtható bemenet nem ad paramétereket. A .exefuttatásához kövesse ezeket a lépéseket:
- Nyisson meg egy konzolablakot abba a könyvtárba, ahol lefordította a RetryAdo2.exe bináris fájlt.
- Futtassa a(z) RetryAdo2.exeprogramot bemeneti paraméterek nélkül.
database_firewall_rules_table 245575913
filestream_tombstone_2073058421 2073058421
filetable_updates_2105058535 2105058535
3. lépés: Az újrapróbálkozás logikája tesztelésének módjai
Az újrapróbálkozási logika teszteléséhez többféle módon is szimulálhat átmeneti hibát.
3.a. lépés: Dobjon egy tesztkivételt
A kódminta a következőket tartalmazza:
- Egy TestSqlExceptionnevű kis másodosztály, Numbernevű tulajdonsággal.
-
//throw new TestSqlException(4060);, amelyet kommentből kivehet.
Ha feloldja a dobási utasítást, és újrafordít, a RetryAdo2.exe következő futtatása az alábbihoz hasonló kimenetet ad ki.
[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\]
>>
3.b. lépés: Állandó hibával való újratesztelés
Annak ellenőrzéséhez, hogy a kód megfelelően kezeli-e az állandó hibákat, futtassa újra az előző tesztet, kivéve, ha nem használja a valós átmeneti hibák( például a 4060) számát. Ehelyett használja a nonszensz számot 7654321. A programnak ezt állandó hibaként kell kezelnie, és meg kell kerülnie az újrapróbálkozásokat.
3.c. lépés: A hálózat leválasztása
- Bontsa le az ügyfélszámítógépet a hálózatról.
- Asztali gép esetén húzza ki a hálózati kábelt.
- Laptop esetén nyomja le a billentyűkombinációt a hálózati adapter kikapcsolásához.
- Indítsa el RetryAdo2.exe, és várja meg, amíg a konzol megjeleníti az első átmeneti hibát, valószínűleg 11001-et.
- Csatlakozzon újra a hálózathoz, amíg a RetryAdo2.exe továbbra is fut.
- Tekintse meg a konzol sikerességét egy későbbi újrapróbálkozás során.
3.d. lépés: A kiszolgáló nevének ideiglenes elírása
- Ideiglenesen adja hozzá a 40615-öt, mint egy másik hibaszámot a TransientErrorNumbers-hez, és fordítsa újra.
- Töréspont beállítása a vonalon:
new QC.SqlConnectionStringBuilder(). - A Szerkesztés és folytatás funkcióval szándékosan elgépelheti a kiszolgáló nevét, néhány sort alább.
- Futtassa a programot, és térjen vissza a törésponthoz.
- A 40615-ös hiba előfordul.
- Javítsa ki a helyesírást.
- Hagyja, hogy a program sikeresen fusson és fejezze be.
- Távolítsa el a 40615-öt, és fordítsa újra.