Почему пул соединений ведет себя по-разному на разных серверах?

У нас есть программа, которая читает поток ввода и записывает его в базу данных. Пользовательского ввода нет.

Эта программа в настоящее время работает параллельно как на сервере разработки, так и на рабочем сервере, с одними и теми же данными в качестве входных данных, записывая их на разные серверы вывода.

На сервере разработки все в порядке; одновременно открыто около 30 с лишним соединений в пуле, и он работает успешно (это может показаться высоким, но мы выполняем несколько последовательных коротких запросов для каждого входа, и имеется большой объем данных). На рабочем сервере он всегда достигает 100 подключений и иногда выдает исключение, указывающее на то, что в пуле закончились доступные подключения.

Есть ли какая-то настройка SQL Server, которая может вызывать это несоответствие? Единственным другим отличием является то, что рабочий сервер находится под дополнительной нагрузкой из различных источников.

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


person Community    schedule 19.02.2009    source источник


Ответы (3)


Ответ оказался неправильным, так как я устанавливал CommandBehaviour.CloseConnection для своих SqlDataReaders (я неправильно использовал побитовую комбинацию). Так что у меня все-таки была утечка соединений.

person Community    schedule 04.03.2009
comment
Помещение их в использование() немного помогло бы, так как вызывалась бы Dispose(), а не просто Close(). Рад, что вы нашли свою проблему. - person Jason Short; 10.06.2009

Обычно, когда вы получаете исключение, говорящее, что вы достигли порога пула соединений, ваш код не закрывает/удаляет соединение должным образом.

Моя теория заключается в том, что вы сталкиваетесь с исключением базы данных в производстве, которое не находится в разработке, и из-за этого ваши соединения остаются открытыми.

Вы всегда должны выполнять свою работу с базой данных в Try/Catch, объявляя соединение и команду снаружи и инициализируя внутри. Вы никогда не должны полагаться на закрытие соединения в блоке try/catch, который всегда закрывается/удаляется в блоке finally:

try
{
    m_Connection = this.getConnection();
    m_Command = this.getCommand();
    m_Command.CommandTimeout = m_ConnectionTimeout;
    m_Command.CommandText = sql;
    m_Command.Connection = m_Connection;
    m_Command.CommandType = CommandType.Text;

    m_Connection.Open();

    return m_Command.ExecuteNonQuery();
}
finally
{
    if (m_Connection != null && m_Connection.State != ConnectionState.Closed)
    {
        m_Connection.Close();
        m_Connection.Dispose();
    }

    if (m_Command != null)
        m_Command.Dispose();
}

Одно приложение действительно не должно потреблять 100 подключений к базе данных. Я бы проверил, правильно ли вы закрываете свои соединения. По крайней мере, поместите журнал, где вы общаетесь с БД, чтобы увидеть, есть ли там исключение.

person Jared    schedule 19.02.2009
comment
Спасибо за это, но, насколько мне известно, в коде нет вызовов Open(), которые не были бы закрыты в «наконец». Кроме того, когда вы смотрите на соединения в мониторе активности, последняя активность для каждого соединения приходится на последнюю минуту, так что я полагаю, что это означает, что они не просочились? - person ; 19.02.2009
comment
Мы также внедрили ведение журнала, но вы совершенно правы, мы получаем больше ошибок на рабочем сервере. Обычно исключения транспортного уровня, которые мы перехватываем, чтобы мы могли повторить запрос, но опять же, все это заключено в try/finally, поэтому все должно быть в порядке.... - person ; 19.02.2009

Пул соединений - это проблема ado.net, потому что SQL-сервер не выполняет пул соединений. Насколько я помню, максимальный размер пула соединений на ado.net составляет 100, поэтому вы находитесь в пределах его максимума. Несколько вещей, которые вы можете попробовать в своем приложении, — это жестко установить пул соединений, используя минимальный размер пула и максимальный размер пула в строке подключения.

Дополнительную информацию можно найти здесь и здесь.

person GregD    schedule 19.02.2009