|
|
|
 |
 |
Nik Legaloff Blog. Connection managment |
 |
|
 |
 |
У всех своя стратегия управления соединениями.
Хочу поделиться своей.
Предпосылки
1. Web приложение
2. За время жизни формы на сервере часто нужны новые соединения.
3. Часто бывает что пока открыто одно соединение, и из него читаются данные, необходимо открывать другие соединения.
4. Допустим что приложение работает пока только с одной БД(один connectionString)
Самое простое решение - каждый раз открывать новое соединение.
ВОт пример.
public static SqlConnection GetNewConnection()
{
// просто каждый раз создаём новое соединение
SqlConnection conection = new SqlConnection(CStr);
return conection;
}
где CStr это кэшируемый connectionString взятый к примеру из config файла
/// <summary>
/// ConnectionString для текущего приложения указанный config файле
/// </summary>
public static string CStr
{
get
{
lock(cstrLock)
{
try
{
if (cstr == null)
{
AppSettingsReader reader = new AppSettingsReader();
cstr = reader.GetValue("ConnectionString", typeof(string)).ToString();
}
}
catch
{
cstr = "connection string по умолчанию";
}
return cstr;
}
}
}
т.е. просто взяли новый connection, поюзали, да главное не забыли его потом закрыть.
Аднака хоть соединения не создаются каждый раз по новой, а берутся из connectionPool которого нам не видно, но всё же это происходит долго.
Пример моей статистики. несколько десятков запросов, каждый создаёт соединение.
половина времени лежала на открытии нового соединения.
тогда созрела такая вот идея.
Сделать свой пул соединений.
Который будет учитывать открытые соединения, используемые, и закрытые.
Причём после того как мы попользовались соединением, мы его отджаём обратно в пул, а там уж смотрим. если оно ещё открыто, то ложим его к открытым. если закрыто, то в закрытые.
а если запрашивается соединение, со в первую очередь оно берётся из открытых, потом смотрим в закрытых(и перед тем как отдать - открываем его). ну и на худой конец создаём новое соединение.при этом прежде чем отдать подготовленное соединение, его регистрируем как активнее.
Вот такая логика. Вроде в стандартном пуле соединений нечто похожее, однако как показала практика, свой пул работает много быстрей.
реализацию можно увидеть в примере кода
ЗЫ. Хранить экземпляр ConnectionPool можно в любом легкодоступном месте.
Я например его храню в DataSession(аналог Session). Это статическая коллекция экземпляров DataSession, каждый из которых привязывается к сессии клиента.
К тому же там удобно хранить экземпляр UnitOfWork или IdentityMap.
Ну нужно не забывать по окончанию реквеста их всех закрывать. Клиент то может не вернуться. Но это уже совсем другая история
Nik Legaloff
10 August 2005 19:27 Комментарии (10)
|
|
|
|
 |
 |
 |
 |
|
|