Запрос не хочет останавливаться!
От: shev  
Дата: 28.11.03 05:42
Оценка:
Здравствуйте!

Есть большая таблица (более 300 млн записей). Требуется банальная вещь — чтобы пользователь мог отменить запрос, посланный ранее.

Запускаю TADODataSet в асинхронном режиме. Смотрю в диспетчер задач — начинает увеличиваться размер потребляемой памяти (вообщем, все ок — данные идут). Вызываю метод Cancel — увеличение памяти прекратилось. Типа все завершилось как надо, записи перестали бежать. Подтверждение тому — событие OnFetchProgress — перестало срабатывать.
Но! Сервер продолжает усиленно работать (это по мигающим лампочкам винчестера видно). Проверяю в Enterprase Manager — у процесса статус runnable. Спустя нескольких минут, когда запрос все же отработает приходит сообщение OnFetchComplete.

Если попытаться еще раз послать запрос (до OnFetchComplete), то выскакивает Exception "Object was open".

Потестировав заметил, что длительность по времени от начала запуска запроса и до OnFetchComplete — одинаковое, независимо от того вызывается метод Cancel или нет. Хотя еще раз напомню, что при вызове Cancel записи действительно прекращают поступать на клиента. При этом, если абсолютно такой же запрос послать из QA и там прекратить его, то сервер мгновенно прекращает работу


DataSet: TADODataSet; 

procedure TForm1.btnStartClick(Sender: TObject); 
begin 
if DataSet.Active then 
DataSet.Close; 

DataSet.ExecuteOptions:=[eoAsyncExecute, eoAsyncFetch]; 

DataSet.CommandText:='select * from table1'; 
//запрос на самом деле с условием выборки, но в данном случае это не важно
DataSet.Open; 
end; 

procedure TForm1.btnStopClick(Sender: TObject); 
begin 
if DataSet.Recordset<>nil then 
begin 
DataSet.Recordset.Cancel; 
DataSet.Recordset.Close; 
end; 
end; 

procedure TForm1.DataSetFetchComplete(DataSet: TCustomADODataSet; 
const Error: Error; var EventStatus: TEventStatus); 
begin 
EventStatus:=esOK; 
memResult.Lines.Add('Выполнение запроса окончено'); 
end; 

procedure TForm1.DataSetFetchProgress(DataSet: TCustomADODataSet; Progress, 
MaxProgress: Integer; var EventStatus: TEventStatus); 
begin 
StatusBar.Panels[0].Text:='Записей: '+IntToStr(Progress); 
end;


Дак почему же он в действительности не останавливается?!
Re: Запрос не хочет останавливаться!
От: _MarlboroMan_ Россия  
Дата: 28.11.03 06:06
Оценка:
Здравствуйте, shev, Вы писали:

S>При этом, если абсолютно такой же запрос послать из QA и там прекратить его, то сервер мгновенно прекращает работу


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

S>Дак почему же он в действительности не останавливается?!


попробуй натравить на QA профилер (да и на свое приложение тоже и сравни результаты) и посмотреть что же он там на самом деле делает. и попробуй повторить. правда есть у меня подозрение что из этой затей мало что получится....
... << RSDN@Home 1.1 beta 2 >>

— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Re[2]: Запрос не хочет останавливаться!
От: shev  
Дата: 28.11.03 06:58
Оценка:
Здравствуйте, _MarlboroMan_, Вы писали:

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


S>>При этом, если абсолютно такой же запрос послать из QA и там прекратить его, то сервер мгновенно прекращает работу


_MM_>ну QA тоже далеко не сразу прекращает колбаситься. и надо бы еще глянуть как при этом себя чувствует сервак.


S>>Дак почему же он в действительности не останавливается?!


_MM_>попробуй натравить на QA профилер (да и на свое приложение тоже и сравни результаты) и посмотреть что же он там на самом деле делает. и попробуй повторить. правда есть у меня подозрение что из этой затей мало что получится....



После остановки в QA сервак сразу прекращает запрос. Проверял просмотром в EM — у процесса состояние sleep. После моей "остановки" у процесса состояние остается running.

А профайлер действительно помог, но не совсем. Появились дополнительные вопросы
Привожу отловленные Profiler'ом команды:

Вот что посылает QA в SQLServer:
select * from rcCalls (index=idx_date) where cl_date between
'21/09/2003 00:00:00' and '25/09/2003 12:00:00'

это мой запрос. И ничего лишнего.

Вот что посылает мой клиент через АДО:

declare @P1 int
set @P1=1
exec sp_prepare @P1 output, NULL, N'select * from rcCalls (index=idx_date) where cl_date between
''21/09/2003 00:00:00''
and ''25/09/2003 12:00:00''
', 1
select @P1

Что за sp_prepare? В BOL про нее кратко написано, что предназначена для подготовки запроса.
Re[3]: Запрос не хочет останавливаться!
От: _MarlboroMan_ Россия  
Дата: 28.11.03 07:17
Оценка:
Здравствуйте, shev, Вы писали:

S>После остановки в QA сервак сразу прекращает запрос. Проверял просмотром в EM — у процесса состояние sleep. После моей "остановки" у процесса состояние остается running.


S>А профайлер действительно помог, но не совсем. Появились дополнительные вопросы

S>Привожу отловленные Profiler'ом команды:

S>Вот что посылает QA в SQLServer:

S>select * from rcCalls (index=idx_date) where cl_date between
S>'21/09/2003 00:00:00' and '25/09/2003 12:00:00'

S>это мой запрос. И ничего лишнего.


угу... они вроде как через DB-Library работают.

S>Вот что посылает мой клиент через АДО:


S>declare @P1 int

S>set @P1=1
S>exec sp_prepare @P1 output, NULL, N'select * from rcCalls (index=idx_date) where cl_date between
S>''21/09/2003 00:00:00''
S>and ''25/09/2003 12:00:00''
S>', 1
S>select @P1

S>Что за sp_prepare? В BOL про нее кратко написано, что предназначена для подготовки запроса.


компилирует запрос. это всё из-за ADO и из-за того что ты используешь параметризованый (я угадал?) запрос.
увы, но ADO работает через набор хранимок типа sp_prepare и sp_executesql. и по сути получается что твой запрос выполняется не от лица клиента, а от лица сервера. и мнится мне что пусть он хоть 100 раз асинхронный, но прервать его выполнение ты не сможешь.
... << RSDN@Home 1.1 beta 2 >>

— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Re[4]: Запрос не хочет останавливаться!
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.11.03 07:31
Оценка: +1
Здравствуйте, _MarlboroMan_, Вы писали:

_MM_>компилирует запрос. это всё из-за ADO и из-за того что ты используешь параметризованый (я угадал?) запрос.

_MM_>увы, но ADO работает через набор хранимок типа sp_prepare и sp_executesql. и по сути получается что твой запрос выполняется не от лица клиента, а от лица сервера. и мнится мне что пусть он хоть 100 раз асинхронный, но прервать его выполнение ты не сможешь.
Можно попробовать disconnect/reconnect. MS SQL вроде как немедленно бросает работать, как только клиентский коннект отпадает.
... << RSDN@Home 1.1 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Запрос не хочет останавливаться!
От: _MarlboroMan_ Россия  
Дата: 28.11.03 07:36
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


_MM_>>компилирует запрос. это всё из-за ADO и из-за того что ты используешь параметризованый (я угадал?) запрос.

_MM_>>увы, но ADO работает через набор хранимок типа sp_prepare и sp_executesql. и по сути получается что твой запрос выполняется не от лица клиента, а от лица сервера. и мнится мне что пусть он хоть 100 раз асинхронный, но прервать его выполнение ты не сможешь.
S>Можно попробовать disconnect/reconnect. MS SQL вроде как немедленно бросает работать, как только клиентский коннект отпадает.

мысль сея не лишена!

тока тогда для выполнения этого запроса надо сделать нарошную коннецию — чтоб остальные компоненты не "страдали" от реконнекта :))
... << RSDN@Home 1.1 beta 2 >>

— сколько программистов надо чтобы заменить сгоревшую лампочку?
— сколько не бери, а лампочку не поменять — проблема аппаратная, программным путем не решается...
Re[6]: Запрос не хочет останавливаться!
От: KGP http://kornilow.newmail.ru
Дата: 28.11.03 07:49
Оценка:
Здравствуйте, _MarlboroMan_, Вы писали:

_MM_>мысль сея не лишена!

_MM_>тока тогда для выполнения этого запроса надо сделать нарошную коннецию — чтоб остальные компоненты не "страдали" от реконнекта :))

Ну да ...
1) в QA запустил я хранимку (долгую)

в профайлере пошло
StmtStarting
StmtCompleted
BatchCompleted



2) в QA запустил я хранимку (долгую) и тут же убиваю QA

в профайлере пошло
StmtStarting
Audit Logout
без StmtCompleted
BatchCompleted
Audit Logout
... << RSDN@Home 1.1 beta 2 >>
Re[7]: Запрос не хочет останавливаться!
От: shev  
Дата: 28.11.03 12:56
Оценка:
>это всё из-за ADO и из-за того что ты используешь параметризованый (я угадал?) запрос.
Нет, не угадал Запрос не параметризованный.

Вот что еще отловил профайлером:

На реально посылаемый запрос в АДО сильно влияет параметр CommandType.

В предыдущем моем после я запускал с CommandType=cmdText. Вот АДО и лепила для него кучу дополнительных строк.
Если запустить с CommandType=cmdUnknown, то АДО ничего своего к запросу не добавляет, но все равно метод Cancel всего-лишь отменяет запрос у клиента, на сервере запрос как продолжал выполнятся, так и продолжает....
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.