Пул подключений
Пул подключений позволяет более эффективно управлять таким ресурсом, как соединение с базой данных. Когда после завершения очередной операции с базой данных вы вызываете метод OleDbConnection.Close(), соединение с базой отправляется в пул и остается открытым там ещё некоторое время. По умолчанию это время - 60 секунд. Когда клиент инициирует новое соединение с базой, провайдер сначала запрашивает его из пула и только потом, если такого не нашлось, создает новый ресурс. Подходит соединение или нет, определяется по точному соответствию свойства ConnectionString с учетом регистра.
Настройка пула подключений осуществляется при помощи параметра строки подключения «Ole Db Services». Значение параметра – это битовая комбинация следующих флагов:
DBPROPVAL_OS_ENABLEALL | -1 | Используются все сервисы |
DBPROPVAL_OS_RESOURCEPOOLING | 1 | Ресурсы должны помещаться в пул |
DBPROPVAL_OS_TXNENLISTMENT | 2 | При необходимости сессии должны быть автоматически подключены к глобальной транзакции |
DBPROPVAL_OS_AGR_AFTERSESSION | 8 | Поддержка операций за пределами сессии |
DBPROPVAL_OS_CLIENTCURSOR | 4 | Поддержка клиентских курсоров на уровне OLE DB Services, если их не поддерживает управляемый провайдер |
DBPROPVAL_OS_DISABLEALL | 0 | Все сервисы отключены |
В примерах к статье класс OleDbServicesValues содержит константы для всех этих флагов. Для комбинации флагов можно использовать операцию побитового исключения (& ~) констант невостребованных сервисов из константы DBPROPVAL_OS_ENABLEALL.
Следующий пример тестирует производительность при использовании различных Ole Db сервисов:
public void OleDbServicesTest() { const int connection_count = 50;
//хранит результат работы по всем операциям
Dictionary<string, double> timeResults = new Dictionary<string, double>();
OleDbConnectionStringBuilder builder = ConnectionProvider.GetConnectionStringBuilderFromUDL();
//OLE DB SERVISES = Все сервисы включены
builder.OleDbServices = OleDbServicesValues.EnableAll; timeResults.Add( String.Format("OLE DB Services=EnableAll ({0})", builder.OleDbServices), DoConnections(builder, connection_count));
//OLE DB SERVISES = все сервисы отключены builder.OleDbServices = OleDbServicesValues.DisableAll; timeResults.Add( String.Format("OLE DB Services=DisableAll ({0})", builder.OleDbServices), DoConnections(builder, connection_count));
//OLE DB SERVICES = все включено, за исключением клиентских курсоров
//и работы за пределами сессии builder.OleDbServices = (OleDbServicesValues.EnableAll & ~ OleDbServicesValues.ClientCursor & ~ OleDbServicesValues.AggregationAfterSession); timeResults.Add( String.Format("OLE DB Services=\n"+ "\tEnableAll & \n" + "\t~ClientCursor & \n" + "\t~AggregationAfterSession ({0})", builder.OleDbServices), DoConnections(builder, connection_count));
foreach (string key in timeResults.Keys) Console.WriteLine(key + ". Seconds elapsed: " + timeResults[key]); }
/// <summary>
/// Открывает и закрывает много подключений, а так же стартует транзакции
/// </summary>
/// <param name="builder"></param>
/// <param name="cnt_connection"></param>
/// <returns>Сколько секунд выполнялось</returns> private double DoConnections(OleDbConnectionStringBuilder builder, int cnt_connection) { DateTime startTime = DateTime.Now;
for (int i = 1; i <= cnt_connection; i++) { OleDbConnection con = new OleDbConnection(builder.ToString()); con.Open(); OleDbTransaction trans = con.BeginTransaction(); trans.Commit(); con.Close(); }
return DateTime.Now.Subtract(startTime).TotalSeconds; }
Наиболее производительным будет вариант при использовании только пула ресурсов и автоматического подключения транзакций – это соответствует битовой маске OleDbServicesValues.EnableAll & ~OleDbServicesValues.ClientCursor &~ OleDbServicesValues.AggregationAfterSession (параметр “OLE DB Services =-13”) .
Чуть медленнее будет работать при использовании всех Ole Db сервисов. И наконец производительность значительно падает (примерно в 20 раз) при полностью выключенных сервисах.
Подробнее об управлении пулом подключений в MSDN - здесь.