Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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
3-1080644592
Крутыш
2004-03-30 15:03
2004.04.25
Почему метод Locate срабатывает один раз.


6-1077801932
Senator
2004-02-26 16:25
2004.04.25
NMHTTP


8-1073893586
Lexer
2004-01-12 10:46
2004.04.25
Нужен DirectX для Delphi7


7-1077726910
Phantomaz
2004-02-25 19:35
2004.04.25
Почему SetWindowsHookEx не пашет, если активно Dos-окно ?


7-1077536316
DuhcmanSoft
2004-02-23 14:38
2004.04.25
Активизация окон





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский