События
31 мар., 23 - 2 апр., 23
Самое большое событие обучения SQL, Fabric и Power BI. 31 марта – 2 апреля. Используйте код FABINSIDER, чтобы сэкономить $400.
Зарегистрироваться сегодняЭтот браузер больше не поддерживается.
Выполните обновление до Microsoft Edge, чтобы воспользоваться новейшими функциями, обновлениями для системы безопасности и технической поддержкой.
Этот раздел содержит пример кода C#, который демонстрирует логику повторных попыток. Логика повторных попыток обеспечивает надежность. Логика повторных попыток предназначена для корректной обработки временных ошибок или временных сбоев, которые обычно устраняются, если программа ожидает несколько секунд, а затем выполняет повторную попытку.
Ниже перечислены источники временных сбоев.
Классы ADO.NET, которые используются для подключения к локальному серверу Microsoft SQL, также можно подключать к базе данных SQL Azure. При этом сами по себе классы ADO.NET необходимый для работы уровень надежности обеспечить не могут. Ваша клиентская программа может испытывать временные сбои, с которыми она должна справляться самостоятельно, продолжая работу без вмешательства пользователя.
Программа должна отличать временные ошибки от постоянных. Временные ошибки — это условия возникновения ошибок, которые можно устранить в течение короткого периода времени, например, временные проблемы с сетью. Примером постоянной ошибки может быть случай, когда программа содержит опечатку в имени целевой базы данных. В этом случае ошибка "No such database found" (Такой базы данных не найдено) будет сохраняться, и не будет устранена в течение короткого времени.
Список номеров ошибок, которые считаются временными сбоями, можно найти в статье Troubleshooting connectivity issues and other errors with Microsoft Azure SQL Database (Устранение неполадок с соединениями и других ошибок с Базой данных SQL Microsoft Azure)
В том примере предполагается, что установлена среда .NET Framework версии 4.6.2 или более поздней версии. Пример кода C# состоит из одного файла с именем Program.cs. Этот код приведен в следующем разделе.
Чтобы скомпилировать пример кода, выполните указанные ниже действия.
Вставьте этот код в ваш файл Program.cs .
Затем необходимо изменить строки для имени сервера, пароля и т. д. Эти строки можно найти в методе с именем GetSqlConnectionString.
ПРИМЕЧАНИЕ. Строка подключения для имени сервера ориентированы на База данных SQL Azure, так как он включает четыре префикса символа tcp:. Однако строку сервера можно настроить на подключение к 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);
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; }
}
Исполняемый файл RetryAdo2.exe не принимает никаких параметров. Чтобы запустить ЕХЕ-файл:
database_firewall_rules_table 245575913
filestream_tombstone_2073058421 2073058421
filetable_updates_2105058535 2105058535
Есть много разных способов имитации временных ошибок для тестирования логики повторных попыток.
Пример кода включает:
//throw new TestSqlException(4060);
, которую можно раскомментировать.Если раскомментировать оператор throw и затем выполнить повторную компиляцию, при следующем выполнении файла RetryAdo2.exe вывод будет примерно следующим.
[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\]
>>
Чтобы убедиться, что код корректно обрабатывает постоянные ошибки, повторно выполните предыдущий тест, но не используйте номер реальной временной ошибки (например, 4060). Вместо этого используйте любой другой номер (например, 7654321). Программа должна обработать этот номер как номер постоянной ошибки, пропуская все повторные попытки.
new QC.SqlConnectionStringBuilder()
.Чтобы изучить другие лучшие практики и рекомендации по проектированию, посетите страницу "Подключение к База данных SQL: ссылки, рекомендации и рекомендации по проектированию"
События
31 мар., 23 - 2 апр., 23
Самое большое событие обучения SQL, Fabric и Power BI. 31 марта – 2 апреля. Используйте код FABINSIDER, чтобы сэкономить $400.
Зарегистрироваться сегодняОбучение
Модуль
Реализация обработки ошибок с помощью Transact-SQL - Training
Реализация обработки ошибок с помощью Transact-SQL
Сертификация
Администрирование инфраструктуры базы данных SQL Server для облачных, локальных и гибридных реляционных баз данных с помощью предложений реляционной базы данных Microsoft PaaS.