Форум: "Базы";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];
ВнизКак правильно отвязать 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;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.078 c