Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.04.25;
Скачать: CL | DM;

Вниз

Как правильно отвязать TADODataSet от сервера?   Найти похожие ветки 

 
Zelius ©   (2004-03-29 17:47) [0]

Есть многопоточное серверное приложение, которое постоянно запрашивает базу данных. Мысль была такая, выполнить запрос, отвязать его от базы и отдать его в другой поток на обработку, а текущий поток пусть выполняет следующий запрос. Как я это делаю:

 ReadUserDataASP.Open;
 UnbindedDS := TADODataSet.Create(nil);
 UnbindedDS.Clone(ReadUserDataASP);
 UnbindedDS.Connection := nil;

дальше я этот UnbindedDS передаю в другой поток. Все работало, но тут стало вылезать сообщение "Could not continue scan with nolock due to data movement". Я так понимаю, что раз эта ошибка вылезает, то значит моя затея с отвязывание не удалась. Прошу совета, как правильно отвязываться наборы данных. Спасибо.


 
Delirium ©   (2004-03-29 17:58) [1]

UnbindedDS.Clone(ReadUserDataASP); - это не копирование рекордеста, а всего лишь новый экземпляр курсора к одим и тем-же данным


 
Nikolay M. ©   (2004-03-29 17:58) [2]


> выполнить запрос, отвязать его от базы и отдать его в другой
> поток на обработку, а текущий поток пусть выполняет следующий
> запрос.

А если по-русски?
Что значит "отвязать" и "отдать его в другой поток"? И каков тайный смысл сих манипуляций?


 
Delirium ©   (2004-03-29 18:01) [3]

> Zelius ©   (29.03.04 17:47)  
С.м. function CopyRecordSet(RecordSet:_RecordSet):_RecordSet;
из http://delphibase.endimus.com/?action=viewfunc&topic=basemssql&id=10112


 
sniknik ©   (2004-03-29 18:02) [4]

скорее проблема на передаче в поток. (а раньше работало, данных меньше было)

еще попробуй nil не коннекту склонированного датасета присвавать а рабочему
типа
UnbindedDS := TADODataSet.Create(nil);
UnbindedDS.Connection := Connection1;
UnbindedDS.CommandText:= ReadUserDataASP.CommandText;
UnbindedDS.Open;
UnbindedDS.Connection := nil;

(оно же там чтото делает на отсоеденении, а если было нил и нил присваивается ... скорее всего проигнорирует (сам в коде посмотри))


 
Zelius ©   (2004-03-30 13:17) [5]


> Delirium ©

хотелось бы обойтись без лишних потоков, ведь должен же быть способ :)


> sniknik ©

попробовал, но оказывается это не работает с процедурами, которые возвращают больше одного рекордсета :(


 
Delirium ©   (2004-03-30 13:26) [6]

"хотелось бы обойтись без лишних потоков" - что-то я не понял, где в функции CopyRecordSet хоть какая-то связь с потоками?


 
Zelius ©   (2004-03-30 13:44) [7]


> Delirium ©

имел ввиду ADOStream

сейчас сделал так
ReadUserDataASP.Open;
UnbindedDS := TADODataSet.Create(nil);
UnbindedDS.Connection := AdoConnection;
UnbindedDS.Clone(ReadUserDataASP);
UnbindedDS.Connection := nil;

посмотрел дебагером - код отрабатывается и рекордсет доступен даже после удалени коннекшена. посмотрим, как будет работать...


 
Delirium ©   (2004-03-30 13:59) [8]

Собственно при операции ReadUserDataASP.Connection := nil;
ReadUserDataASP то-же будет доступен, ни куда не денется, я не понимаю зачем тебе Clone ?


 
Zelius ©   (2004-03-30 14:23) [9]

смысл в том, что бы разбить выборку данных и обработку на две части, проц. ReadUserDataASP возвращает два набора данных, потом я делаю
 ReadUserDataASP.RecordSet := ReadUserDataASP.NextRecordset(i);
и повторяю процедуру с клонированием. после этого данные передаются на обработку в другой поток, а текущий выполняет след. запрос.


 
Delirium ©   (2004-03-30 14:57) [10]

Но Clone - не копирует данные, он создаёт курсор к тем-же данным, т.е. новый элемент управления и всё.


 
Zelius ©   (2004-03-30 15:17) [11]

А если после всех этих манипуляций вызывается ReadUserDataASP.Close, и после этого отдаются рекрдсеты, то ведь получается же отвязанный набор данных? Если подумать, то это даже хорошо, что бы не было лишнего дублирования.


 
Delirium ©   (2004-03-30 15:39) [12]

В общем я так и не понял для чего ты тут используешь Clone, ну и ладно 8-/


 
jocko ©   (2004-03-30 15:39) [13]

вообще не понятно "отвязать его от базы и отдать его в другой поток на обработку" предполагается что приложение само обрабатыват данные и при том в клиенте ?...
В этом случае проще написать хранимые процедуры и обрабатывать данные на сервере.
PS А если "отвязывать" набор данных, то чем плох ltBatchOptimistic?


 
Delirium ©   (2004-03-30 15:54) [14]

Да "отвязывать" то элементарно, а вот клонировать зачем?


 
Zelius ©   (2004-03-30 16:38) [15]

А как? Есть проц. которая возвращает два набора, как их отдать так, что они не были привязаны к базе?


 
Zelius ©   (2004-03-30 16:39) [16]


> jocko ©

мне надо из данных построить xml страницу и отдать юзеру.


 
jocko ©   (2004-03-30 16:53) [17]

>15
NextRecordset + ltBatchOptimistic


 
Delirium ©   (2004-03-30 16:58) [18]

"как их отдать так, что они не были привязаны к базе?"
...
UnbindedDS := TADODataSet.Create(nil);
UnbindedDS.Recordset:=ReadUserDataASP.Recordset.NextRecordset(v);
UnbindedDS.Connection := nil;
...

где тут необходим Clone ?


 
Zelius ©   (2004-03-30 17:08) [19]


> Delirium ©   (30.03.04 16:58) [18]

это второй, а первый датасет?


 
Zelius ©   (2004-03-30 17:08) [20]


> jocko ©   (30.03.04 16:53) [17]

ок, посмотрю что такое ltBatchOptimistic...


 
Delirium ©   (2004-03-30 17:29) [21]

"это второй, а первый датасет?" - а самому подумать?

procedure TForm1.Button1Click(Sender: TObject);
var R:_RecordSet;
   v:OleVariant;
   i:integer;
   Rs:array of _RecordSet;

begin
SetLength(Rs, 1);
Rs[0]:=ADOQuery1.Recordset;
while true do
begin
R:=ADOQuery1.Recordset.NextRecordset(v);
if R<>nil then
 begin
 i:=Length(Rs);
 SetLength(Rs, i+1);
 Rs[i]:=R;
 end
else break;
end;
end;


 
Zelius ©   (2004-03-30 17:52) [22]


> jocko ©

хмм... а при чем тут ltBatchOptimistic? Я вообще ничего не меняю...


 
Zelius ©   (2004-03-30 17:58) [23]


> Delirium ©   (30.03.04 17:29) [21]

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


 
Delirium ©   (2004-03-30 18:13) [24]

"когда я закрою основную хр.проц., то остальные будут ссылаться на закрытые же данные" - тут не всё так просто, когда ты уничтожаешь ADODataSet, ты вовсе не уничтожаешь _RecordSet - он, как честный COM, живёт до тех пор пока на него есть ссылки, коими и являются элемены массива из моего примера. Их элементарно можно перемещать между потоками, т.к. это позволяет COM-архитектура ADO.


 
Delirium ©   (2004-03-30 18:37) [25]

К слову чтобы "оторвать" _Recordset от сервера, вовсе нет необходимости оборачивать его TADODataSet, достаточно вызвать соответствующий метод (Rs[0].Set_ActiveConnection(nil);).


 
Zelius ©   (2004-03-31 11:43) [26]


> Delirium ©   (30.03.04 18:37) [25]

попробую... спасибо!



Страницы: 1 вся ветка

Текущий архив: 2004.04.25;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.024 c
1-1081246688
Вова
2004-04-06 14:18
2004.04.25
Как убрать колонтитулы при печати из TWebBrowser


14-1081168443
senator
2004-04-05 16:34
2004.04.25
Как получить хендел окна текущего приложения?


1-1081594405
XXXXXXXXXXX
2004-04-10 14:53
2004.04.25
Работа с Файлами больших размеров ()


4-1074510385
Oyster
2004-01-19 14:06
2004.04.25
Какой диалог подстраивается под язык системы?


7-1077797937
Программер
2004-02-26 15:18
2004.04.25
Работа с USB