Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
ADO: CursorLocation=adUseServer. При каждом вызове SP создается новая сессия (+)
|
|||
|---|---|---|---|
|
#18+
Имеем проблему: Есть приложение, работающее с MSSQL Server 7/2000 через ADO. При работе выполнялись запросы, с установленным параметром CursorLocation=adUseClient. И все было нормально.. Пока не решили переделать приложение, чтобы запросы выполнялись параметром CursorLocation=adUseServer. И обнаружилась интересная фича: если в какой-то момент времени есть открытый серверный курсор, то при попытке вызвать хранимую процедуру (SP) ADO создает дополнительную сессию. В этой сессии выполняется SP, после чего сессия закрывается. И все бы хорошо, да и почти не заметно для неискушенного, но есть 2 проблемы в связи с этим: 1) Во многих хранимых процедурах используется идентификатор текущей сессии (@@SPID), например для определения того, заблокирован объект или нет и т.д. 2) Если используется Application role, то в новой сессии она не активизируется и у пользователя отсутствую права на выполнение SP. Переделывать логику приложения в связи с этой особенностью ADO не хочется. Посему вопрос: может кто с этим сталкивался и знает как эту фичу отключить или как с ней правильно бороться. Для того чтобы наглядно представить проблему привожу тестовый пример, иллюстрирующий особенность проблемы. 1) На сервере создаем две таблицы и одну SP. При вызове SP в эти таблицы пишется идентификатор сессии в рамках которой была вызвана процедура create table t1 ("ID" INT) go select * into t2 from master..sysprocesses where 1=2 go create procedure p1 as begin insert into t1 values (@@SPID) insert into t2 select * from master..sysprocesses where spid=@@SPID end; go 2) Далее из клиенского приложения выплняем примерно такой код: ADOConnection = CreateObject("ADODB.Connection"); ADOConnection.ConnectionString="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=landocs2000;Data Source=MICHAIL\MSSQL2000;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=MICHAIL;Use Encryption for Data=False;Tag with column collation when possible=False"; ADOConnection.CursorLocation = 2; //adUseServer ADOConnection.ConnectionTimeOut = 600; ADOConnection.CommandTimeOut = 600; ADOConnection.IsolationLevel = 4096; //adXactReadCommitted ADOConnection.Mode = 0; //adModeUnknown ADOConnection.Open(); ADOCmd0 = CreateObject("ADODB.Command"); ADOCmd0.ActiveConnection = ADOConnection; ADOCmd0.CommandTimeout = 600; ADOCmd0.CommandText="p1"; ADOCmd0.CommandType=4; //adCmdStoredProc ADOCmd0.Execute(); ADOCmd1 = CreateObject("ADODB.Command"); ADOCmd1.ActiveConnection = ADOConnection; ADOCmd1.CommandTimeout = 600; ADOCmd1.CommandText="SELECT * FROM sysobjects"; Rs1 = ADOCmd1.Execute(); ADOCmd2 = CreateObject("ADODB.Command"); ADOCmd2.ActiveConnection = ADOConnection; ADOCmd2.CommandTimeout = 600; ADOCmd2.CommandText="p1"; ADOCmd2.CommandType=4; //adCmdStoredProc ADOCmd2.Execute(); Rs1.MoveFirst(); While Rs1.EOF()=0 Do Message(Rs1.Fields("ID").Value); Rs1.MoveNext(); EndDo; Rs1.Close(); ADOCmd3 = CreateObject("ADODB.Command"); ADOCmd3.ActiveConnection = ADOConnection; ADOCmd3.CommandTimeout = 600; ADOCmd3.CommandText="p1"; ADOCmd3.CommandType=4; //adCmdStoredProc ADOCmd3.Execute(); После выполнения этого кода посмотрим, что есть в таблицах t1 и t2 select * from t1 select * from t2 Видим, что идентификаторы сессий разные. Это говорит о том, что процедура, которая вызывалась объектом ADOCmd2, выполнялась в отдельной сессии. Если CursorLocation изменить на adUseClient - то все OK. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.01.2002, 10:33 |
|
||
|
ADO: CursorLocation=adUseServer. При каждом вызове SP создается новая сессия (+)
|
|||
|---|---|---|---|
|
#18+
В общем-то, это всем известно. Что тебя так поразило? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.01.2002, 15:32 |
|
||
|
ADO: CursorLocation=adUseServer. При каждом вызове SP создается новая сессия (+)
|
|||
|---|---|---|---|
|
#18+
Если это всем известно - уже хорошо. А можно ли где-нибудь про это почитать. И с этим ка-нибудь можно бороться. Нас так совсем не устраивает и чего делать не знаем. Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.01.2002, 15:59 |
|
||
|
ADO: CursorLocation=adUseServer. При каждом вызове SP создается новая сессия (+)
|
|||
|---|---|---|---|
|
#18+
Где прочитать, так с ходу не скажу. Наверно, в MSDN есть. А суть проста - ADO таким образом обходит ограничение протокола TDS, который не позволяет одновременно фетчить несколько наборов данных в одной сессии. Если бы ADO так не поступало, то при открытии серверного курсора больше ничего невозможно было бы сделать до его закрытия. Решение тоже на поверхности - не использовать серверные курсоры. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.01.2002, 06:29 |
|
||
|
ADO: CursorLocation=adUseServer. При каждом вызове SP создается новая сессия (+)
|
|||
|---|---|---|---|
|
#18+
Понятно. Только вот если использовать провайдер ODBC-шный, то все нормально работает - никаких дополнительных сессий не открывается. Я всегда думал, что в ODBC используется аналог серверного курсора. И как в этом случае обходится ограничение TDS? Или он тут вообще не используется? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.01.2002, 07:28 |
|
||
|
ADO: CursorLocation=adUseServer. При каждом вызове SP создается новая сессия (+)
|
|||
|---|---|---|---|
|
#18+
А вот только что увидел SET CONTEXT_INFO, Associates up to 128 bytes of binary information with the current session or connection. Похоже это выход. Клиентское приложение создает соединение (application role). Оператор вводит логин для работы с базой и этот логин будем указывать в качестве CONTEXT_INFO для каждого соединения со стороны клиента. Тогда всегда cможем узнать хозяина для клиентского процесса. Сейчас буду пробовать. MSDN: context information for session ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2002, 02:38 |
|
||
|
ADO: CursorLocation=adUseServer. При каждом вызове SP создается новая сессия (+)
|
|||
|---|---|---|---|
|
#18+
2. Dmitry Интерестно все это, но только вот не понятен такой момент: Если создается ADO-шная сессия для вызова SP (назовем эту сесси дочерней), то у нее CONTEXT_INFO будет незаполненным и непонятно каким образом узнать SPID сессии, которая ее (дочернюю сессию) породила. Кроме того, каким образом для этой дочерней сессии делать set_approle тоже непонятно. Короче мы решили от серверных курсоров отказываться напрочь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2002, 08:09 |
|
||
|
|

start [/forum/topic.php?fid=46&fpage=3510&tid=1824141]: |
0ms |
get settings: |
5ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
36ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
43ms |
get tp. blocked users: |
1ms |
| others: | 229ms |
| total: | 346ms |

| 0 / 0 |
