Проблемы с соединением SQL - PullRequest
       8

Проблемы с соединением SQL

0 голосов
/ 28 августа 2011

У нас есть вспомогательный класс, который мы используем для вызова хранимых процедур на SQL Server. Вспомогательная функция выглядит так:

using (sqlCon = new SqlConnection(connectionString))
        {

            // Create database command object
            sqlCmd = sqlCon.CreateCommand();
            sqlCmd.CommandTimeout = commandTimeout;

            // Set command text AND command type
            sqlCmd.CommandText = procedureName;
            sqlCmd.CommandType = CommandType.StoredProcedure;

            // Set command parameters
            if (paramCollection != null)
            {
                foreach (DatabaseParameter dbParam in paramCollection)
                {
                    SqlParameter sqlParam = sqlCmd.Parameters.Add(dbParam.ParameterName, dbParam.ParameterType);
                    sqlParam.Direction = dbParam.ParameterDirection;
                    sqlParam.Value = dbParam.ParameterValue;
                    if (dbParam.ParameterSize != -1)
                        sqlParam.Size = dbParam.ParameterSize;
                    if (dbParam.ParamPrecision != -1)
                        sqlParam.Precision = (byte)dbParam.ParamPrecision;
                    if (dbParam.ParamScale != -1)
                        sqlParam.Scale = (byte)dbParam.ParamScale;
                }
            }

            try
            {
                sqlCon.Open();
            }
            catch
            {
                SqlConnection.ClearAllPools();
                sqlCon.Open();
            }

            // Prepare command
            sqlCmd.Prepare();

            // Execute the statement
            sqlCmd.ExecuteNonQuery();

            if (sqlCmd.Parameters.Contains("@Result"))
                return sqlCmd.Parameters["@Result"].Value;
            else
                return "Completed";
        }

Итак, мы следим за тем, чтобы соединения были правильно закрыты. Приложение является многопоточным сервисом, и все потоки вызывают этот метод довольно регулярно. Мы блокируем (thisobject) {} разделы вокруг кода, который вызывает вышеупомянутый вспомогательный метод, чтобы предотвратить кражу потоков друг с другом.

Connection.Open находится внутри перехватчика с ClearAllpools для очистки разорванных соединений.

Однако через день мы периодически получаем следующий список ошибок.

Текущее состояние соединения подключается.

или

Текущее состояние соединения открыто.

Ошибки возникают примерно один раз в несколько тысяч раз, когда вызывается код, поэтому устранять неполадки довольно сложно. Кто-нибудь видел что-нибудь подобное или идеи о том, что может быть не так?

Ответы [ 3 ]

1 голос
/ 28 августа 2011

Ну, я не могу точно сказать, почему происходит сбой соединения. Но что неправильно - это ваш catch блок. Вы игнорируете фактическую ошибку и заменяете ее бесполезной (той, которую вы видите).

Никогда игнорировать исключения. Они выбрасываются по какой-то причине и, как правило, содержат полезную информацию о непредвиденной ошибке, с которой столкнулась система. У вас проблемы с выяснением проблемы, потому что вы выбрасываете эту полезную информацию, даже не глядя на нее.

Ошибки, которые вы видите, исходят из кода в вашем блоке catch. Этот код, по сути, пытается сделать именно то, что просто не удалось, но немного по-другому. Вам нужно зарегистрировать свою ошибку, чтобы вы могли выяснить причину ее сбоя и в первую очередь достичь блока catch.

Хорошее практическое правило для блоков try/catch заключается в том, что вы должны ловить исключение, только если вы готовы обработать исключение. Здесь вы не обращаетесь с этим вообще, поэтому, если вы не сделаете это, вы должны просто полностью удалить try/catch. Пусть исключение всплывает где-то, что оно может быть обработано. В качестве альтернативы, замените код в блоке catch на запись некоторых ошибок и выйдите из блока кода полезным и значимым способом (верните ошибку в вызывающий блок кода, сгенерируйте пользовательское исключение с перехваченным исключением внутри него и т. Д. ).

1 голос
/ 28 августа 2011

Я сталкивался с этими типами ошибок при работе с многопоточным приложением, даже при использовании lock.После бесконечных часов отладки я так и не нашел проблему и попытался повторно подключиться несколько раз, прежде чем сдаться.На сегодняшний день я не видел, чтобы ошибка возникла снова.

int retries = 5;
while( true )
{
    try
    {
        DbCommand cmd = GetCommand( sql );
        using( DbConnection conn = cmd.Connection )
        {
            conn.Open();
            // do stuff
            break;
        }
    }
    catch
    {
        Thread.Sleep( 1000 );
        if( retries-- <= 0 )
        {
            throw;
        }
    }
}
0 голосов
/ 28 августа 2011

Кроме всего прочего, вы пытались действовать условно, исходя из State?

using (sqlCon = new SqlConnection(connectionString))
{
    if (sqlCon.State == ConnectionState.Open)
    {
        ....
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...