Безопасно ли полагаться на SqlConnection retry logi c при использовании SqlCommand? - PullRequest
0 голосов
/ 27 февраля 2020

Я использовал блок Microsoft.Practice.TransientFaultHandling для повторной логики c. Теперь я переключил свое приложение на. Net 4.8 и использую новую сборку в журнале повторов c для SqlConnection. Мне было интересно, нужна ли мне специальная логика повторов c для моего SqlCommand (я раньше использовал Polly) или это тоже встроено. Нет возможности записать повтор при попытке полагаться на встроенные функции, что делает его действительно сложным проверить.

Microsoft заявляет здесь :

"Есть тонкость. Если во время выполнения запроса возникает временная ошибка, ваш объект SqlConnection не Не пытайтесь повторить операцию подключения. Конечно, он не повторяет ваш запрос. Однако SqlConnection очень быстро проверяет соединение перед отправкой запроса на выполнение. Если бы при быстрой проверке обнаруживается проблема с соединением, SqlConnection повторяет операцию соединения. Если повторная попытка завершится успешно , ваш запрос отправлен на выполнение. "

Я проверил это, просто отключив и повторно подключив inte rnet в пределах интервала времени повтора, и моя команда была выполнена через некоторое время. Так что, похоже, работает для этого простого сценария. Но действительно ли можно положиться на это, или мне все еще нужно реализовать повторную логику c для моего SqlCommand?

Вот мой код:

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(ConnectionString); 
builder.ConnectRetryCount = 5;
builder.ConnectRetryInterval = 3;

MyDataSet m_myDataSet = new MyDataSet();
using (SqlConnection sqlConnection = new SqlConnection(builder.ConnectionString)) 
{
   try
    {
       sqlConnection.Open();
    }
    catch (SqlException sqlEx)
    {
        // do some logging                          
        return false;
    }
    try
    {
        using (SqlCommand cmd = new SqlCommand(selectCmd, sqlConnection))
        {                                         
              using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                {
                    da.Fill(m_myDataSet, tableName);
                }                          
        }
    }           
}

1 Ответ

0 голосов
/ 27 февраля 2020

Ответ на ваш вопрос заключается в том, чтобы проанализировать, почему ваше соединение с базой данных открыто так долго, что оно простаивает и истекает время ожидания. Свойства ConnectRetryCount и ConnectRetryInterval позволяют настроить попытки переподключения после того, как сервер обнаружит сбой простоя соединения. Я бы следовал рекомендациям Microsoft по этому вопросу:

Рекомендация по пулу соединений

Мы настоятельно рекомендуем всегда закрывать соединение, когда вы его заканчиваете, так что соединение будет возвращено в пул. Это можно сделать с помощью методов Close или Dispose объекта Connection, или открыв все соединения внутри оператора using в C#, или оператора Using в Visual Basi c. Соединения, которые явно не закрыты, могут не быть добавлены или возвращены в пул. Дополнительные сведения см. В разделе «Оператор» или «Как: удалить системный ресурс для Visual Basi» c.

Открывайте свои соединения и закрывайте их, когда они больше не нужны, например:

MyDataSet m_myDataSet = new MyDataSet();

try
{
    using (SqlConnection sqlConnection = new SqlConnection(ConnectionString))
    {
        sqlConnection.Open();

        using (SqlCommand cmd = new SqlCommand(selectCmd, sqlConnection))
        {
            using (SqlDataAdapter da = new SqlDataAdapter(cmd))
            {
                da.Fill(m_myDataSet, tableName);
            }
        }
    }
}
catch (SqlException sqlEx)
{
    // do some logging
    return false;
}

Надеюсь, это поможет.

Удачного кодирования !!!

...