Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
- Önceki makale: 3. Adım: ADO.NET kullanarak SQL'e bağlanma kavram kanıtı
Bu makalede, özel yeniden deneme mantığını gösteren bir C# kod örneği sağlanır. Yeniden deneme mantığı güvenilirlik sağlar. Yeniden deneme mantığı, program birkaç saniye bekleyip yeniden denerse kaybolma eğilimi gösteren geçici hataları veya geçici hataları düzgün bir şekilde işlemek için tasarlanmıştır.
Geçici hata kaynakları şunlardır:
- İnternet'i destekleyen ağlarda kısa bir hata.
- Bir bulut sistemi, sorgunuz gönderildiği anda kaynaklarına yük dengelemesi yapıyordur.
Yerel Microsoft SQL Server'ınıza bağlanmak için ADO.NET sınıfları da Azure SQL Veritabanı'na bağlanabilir. Ancak, ADO.NET sınıfları kendi başlarına üretim kullanımında gerekli olan tüm sağlamlığı ve güvenilirliği sağlayamaz. İstemci programınız sessizce ve düzgün bir şekilde kurtarılıp kendi başına devam etmesi gereken geçici hatalarla karşılaşabilir.
1. Adım: Geçici hataları tanımlama
Programınız geçici hatalar ile kalıcı hatalar arasında ayrım yapmalıdır. Geçici hatalar, geçici ağ sorunları gibi kısa bir süre içinde temizlenebilen hata koşullarıdır. Kalıcı bir hata örneği, programınızda hedef veritabanı adının yanlış yazılması durumunda "Böyle bir veritabanı bulunamadı" hatasının kalıcı olması ve kısa bir süre içinde temizleme şansı olmaması olabilir.
Geçici hatalar olarak kategorilere ayrılan hata numaralarının listesi SQL Veritabanı istemci uygulamaları için hata iletileri bölümünde bulunabilir
2. Adım: Örnek uygulama oluşturma ve çalıştırma
Bu örnekte .NET Framework 4.6.2 veya sonraki bir sürümün yüklü olduğu varsayılır. C# kod örneği Program.cs adlı bir dosyadan oluşur. Kodu bir sonraki bölümde verilmektedir.
Adım 2.a: Kod örneğini yakalama ve derleme
Örneği aşağıdaki adımlarla derleyebilirsiniz:
-
Ücretsiz Visual Studio Community sürümünde, C# Konsol Uygulaması şablonundan yeni bir proje oluşturun.
- Dosya > Yeni > Proje > Yüklü > Şablonlar > Visual C# > Windows > Klasik Masaüstü > Konsol Uygulaması
- Projeyi RetryAdo2 olarak adlandırın.
- Çözüm Gezgini bölmesini açın.
- Projenizin adına bakın.
- Projenizde, Microsoft.Data.SqlClient paketine bir NuGet bağımlılığı ekleyin .
- Program.cs dosyasının adına bakın.
- Program.cs dosyasını açın.
- Program.cs dosyasının içeriğini aşağıdaki kod bloğundaki kodla tamamen değiştirin.
- Derle > Çözümü Derle menüsünü seçin.
2.b. Adım: Örnek kodu kopyalama ve yapıştırma
Bu kodu Program.cs dosyanıza yapıştırın.
Ardından, sunucu adı, parola vb. için dizeleri düzenlemeniz gerekir. Bu dizeleri GetSqlConnectionString adlı yöntemde bulabilirsiniz.
Uyarı
Sunucu adı için bağlantı dizesi, tcp: öğesinin dört karakterlik ön ekini içerdiğinden Azure SQL Veritabanı'na yöneliktir. Ancak, Microsoft SQL Server'ınıza bağlanmak için sunucu dizesini ayarlayabilirsiniz.
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. Adım: Programı çalıştırma
RetryAdo2.exe yürütülebilir dosyası parametre almaz. .exe çalıştırmak için:
- RetryAdo2.exe ikili dosyasını derlediğiniz bir konsol penceresi açın.
- giriş parametresi olmadan RetryAdo2.exeçalıştırın.
database_firewall_rules_table 245575913
filestream_tombstone_2073058421 2073058421
filetable_updates_2105058535 2105058535
3. Adım: Yeniden deneme mantığınızı test etmenin yolları
Yeniden deneme mantığınızı test etmek için geçici bir hatanın benzetimini yapmanın çeşitli yolları vardır.
3.a. Adım: Test istisnası fırlatma
Kod örneği şunları içerir:
- Number adlı bir özelliğe sahip TestSqlException adlı küçük bir ikinci sınıf.
-
//throw new TestSqlException(4060);ögesinin yorumunu kaldırabilirsiniz.
"Throw deyimini yorumu kaldırarak yeniden derlerseniz, RetryAdo2.exe'nin sonraki çalıştırması aşağıdakine benzer bir çıkış üretir."
[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. Adım: Kalıcı bir hatayla yeniden test etme
Kodun kalıcı hataları doğru işlediğini kanıtlamak için önceki testi yeniden çalıştırın, ancak 4060 gibi gerçek bir geçici hatanın sayısını kullanmayın. Bunun yerine 7654321 saçma numarasını kullanın. Program bunu kalıcı bir hata olarak değerlendirmeli ve yeniden denemeyi atlamalıdır.
3.c. Adım: Ağ bağlantısını kesme
- İstemci bilgisayarınızın ağ bağlantısını kesin.
- Masaüstü için ağ kablosunu çıkarın.
- Dizüstü bilgisayar için, ağ bağdaştırıcısını kapatmak için tuşların işlev bileşimine basın.
- RetryAdo2.exebaşlatın ve konsolun ilk geçici hatayı (büyük olasılıkla 11001) görüntülemesini bekleyin.
- RetryAdo2.exe çalışmaya devam ederken ağa yeniden bağlanın.
- Sonraki bir yeniden denemede konsol raporunun başarısını izleyin.
Adım 3.d: Sunucu adını geçici olarak yanlış yazın
- Geçici olarak 40615'i TransientErrorNumbers'a başka bir hata numarası olarak ekleyin ve yeniden derle.
- Satırda bir kesme noktası ayarlayın:
new QC.SqlConnectionStringBuilder(). - Düzenle ve Devam Et özelliğini kullanarak aşağıdaki birkaç satırda sunucu adını bilerek yanlış yazın.
- Programın çalışmasına ve kesme noktanıza geri dönmesine izin verin.
- Hata 40615 oluşur.
- Yazım hatalarını düzeltin.
- Programın başarıyla çalıştırılmasına ve bitmesine izin verin.
- 40615'i kaldırın ve yeniden derle.