Многопоточность: одновременное выполнение многих запросов
От: Kimus  
Дата: 23.08.07 14:27
Оценка:
Я пишу многопоточную объектно-ориентированную программу на C#, которая работает с MSSQL2005. При этом различные классы реализуют функционал доступа к базе данных — интерфейс класса ориентирован на логику работы программы, а в реализации методов и свойств "зашита" логика работы с базой данных.

При этом часто возникают ситуации, когда требуется одновременное выполнение множества SQL-запросов из разных потоков.

Вопрос состоит в следующем — как в этом случае лучше организовать соединение с базой данных (SqlConnection) в такой многопоточной среде? Я вижу два варианта:

(1) сложный: иметь столько соединений, сколько запущено потоков, и в каждом потоке использовать свое соединение. Реализовать это можно, например, с помощью глобального объекта Dictionary<int, SqlConnection>, где ключом будет ID обращающегося потока, и класса-оболочки DataBaseConnection, статическое свойство Connection которого будет проверять, есть ли в словаре соединение для текущего потока и, если нет — то создавать его. Идея кажется интересной, но возникают накладные расходы, связанные с обращением к свойству, поиску в словаре, плюс надо как-то отслеживать завершение работы потоков и закрывать соответствующие соединения

(2) простой: перед выполнением любого запроса (или набора запросов, которые гарантированно выполняются в одном потоке) создавать новое соединение с БД, а потом закрывать его?

Хочу узнать ваше мнение — какой метод лучше?

велики ли накладные расходы на создание соединения (запросов довольно много)? Как можно недорого отследить завершение/создание потока в первом способе (кроме проверки словаря)?
Re: Многопоточность: одновременное выполнение многих запрос
От: Svjat Украина  
Дата: 23.08.07 14:32
Оценка: +2
Здравствуйте, Kimus, Вы писали:

K>Вопрос состоит в следующем — как в этом случае лучше организовать соединение с базой данных (SqlConnection) в такой многопоточной среде? Я вижу два варианта:


K>(1) сложный: иметь столько соединений, сколько запущено потоков, и в каждом потоке использовать свое соединение. Реализовать это можно, например, с помощью глобального объекта Dictionary<int, SqlConnection>, где ключом будет ID обращающегося потока, и класса-оболочки DataBaseConnection, статическое свойство Connection которого будет проверять, есть ли в словаре соединение для текущего потока и, если нет — то создавать его. Идея кажется интересной, но возникают накладные расходы, связанные с обращением к свойству, поиску в словаре, плюс надо как-то отслеживать завершение работы потоков и закрывать соответствующие соединения


а стандартный пул соединений уже не подходит?
Re[2]: Многопоточность: одновременное выполнение многих зап
От: Kimus  
Дата: 23.08.07 16:51
Оценка:
Здравствуйте, Svjat, Вы писали:

S>а стандартный пул соединений уже не подходит?


Я не знал, что они существуют. Сейчас почитал о нем, узнал. Спасибо.

Пробую такой тест:

str = @"Data Source=(local)\SQLEXPRESS;Initial Catalog=mq6;Integrated Security=True;";
for (int i = 0; i < 10000; i++)
{
using (SqlConnection s = new SqlConnection(str))
{
s.Open();
s.Close();
}
занимает 4 секунды.

если строку заменить на
str = @"Data Source=(local)\SQLEXPRESS;Initial Catalog=mq6;Integrated Security=True;Connection Lifetime=1000;Pooling=true;Max Pool Size=80;Min Pool Size=10;";

то занимает тоже 4 секунды.

это
(1) у меня ничего не работает?
или
(2) пул есть в любом случае, поэтому явная его настройка не чувствуется?

если (1) то что не правильно?
Re: Многопоточность: одновременное выполнение многих запрос
От: _d_m_  
Дата: 24.08.07 02:33
Оценка:
Здравствуйте, Kimus, Вы писали:

K>(2) простой: перед выполнением любого запроса (или набора запросов, которые гарантированно выполняются в одном потоке) создавать новое соединение с БД, а потом закрывать его?


Именно так. Здесь в игру вступает Connection Pool.
Re[2]: Многопоточность: одновременное выполнение многих зап
От: _d_m_  
Дата: 24.08.07 02:35
Оценка:
Здравствуйте, Svjat, Вы писали:

S>Здравствуйте, Kimus, Вы писали:


K>>Вопрос состоит в следующем — как в этом случае лучше организовать соединение с базой данных (SqlConnection) в такой многопоточной среде? Я вижу два варианта:


K>>(1) сложный: иметь столько соединений, сколько запущено потоков, и в каждом потоке использовать свое соединение. Реализовать


S>а стандартный пул соединений уже не подходит?


А что, до варианта (2) в исходном сообщении ты недошел?
Re: Многопоточность: одновременное выполнение многих запрос
От: Slider_spb Россия  
Дата: 24.08.07 08:20
Оценка:
Если во втором случае коннекты не будут гарантирванно закрываться — можно нарваться на исчерпание пула коннектов. Я несколько раз нарывался.
Re[3]: Многопоточность: одновременное выполнение многих зап
От: Lloyd Россия  
Дата: 24.08.07 10:14
Оценка: 1 (1) +1
Здравствуйте, Kimus, Вы писали:

K>это

K>(1) у меня ничего не работает?
K>или
K>(2) пул есть в любом случае, поэтому явная его настройка не чувствуется?

Пул по умолчанию создается, если явно не указано Pooling=false
Re[3]: Многопоточность: одновременное выполнение многих зап
От: Svjat Украина  
Дата: 25.08.07 11:29
Оценка:
Здравствуйте, _d_m_, Вы писали:

K>>>(1) сложный: иметь столько соединений, сколько запущено потоков, и в каждом потоке использовать свое соединение. Реализовать


S>>а стандартный пул соединений уже не подходит?


___>А что, до варианта (2) в исходном сообщении ты недошел?


дошел, просто второй вариант был про накладные расходы при реальном open/close.
а прочитав про пул автор и так все сам понял.

согласен, что можно было сразу подробнее ответить, замечание принято
но вобщем в ветке уже все сказали.
Re[2]: Многопоточность: одновременное выполнение многих зап
От: Svjat Украина  
Дата: 25.08.07 11:35
Оценка:
Здравствуйте, _d_m_, Вы писали:

___>Здравствуйте, Kimus, Вы писали:


K>>(2) простой: перед выполнением любого запроса (или набора запросов, которые гарантированно выполняются в одном потоке) создавать новое соединение с БД, а потом закрывать его?


___>Именно так. Здесь в игру вступает Connection Pool.


все так, но вот беда — если пользоваться пулом не зная о его существовании, можно легко "попасть"

много раз видел, когда девелоперы начиная работать с бд
копипейстят из примеров конекшн стринг вместе с "pooling=false" не понимая зачем это.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.