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

Вниз

Запрос к базе из потоков   Найти похожие ветки 

 
RomanFromMD   (2003-02-03 17:10) [0]

Для запроса к базе создается два потока. В каждом потоке выполняется запрос к разным таблицам одной базы Interbase.
Проблема в том что иногда я получаю результат из обоих потоков,
а иногда только из одного, при том что нельзя определить из которого будет получен результат. Если я создаю не два потока а один то все отлично работает. Подскажите в чем проблема. Может быть причина в ограничениях на одновременное кол-во соединений, хотя я использую Interbase Server 6.0 и в принцепе их не должно быть. Заранее спасибо.


 
Val ©   (2003-02-03 17:40) [1]

17 строчка?


 
RomanFromMD   (2003-02-03 18:44) [2]

17 строчка чего? Я не понял вопрос.


 
Val ©   (2003-02-03 18:58) [3]

вашей программы конечно.
как можно помочь в данном случае, не видя исходного текста?


 
RomanFromMD   (2003-02-03 19:46) [4]

interface

uses
Classes,IBDatabase,IBQuery,DB,SysUtils,SyncObjs;
type
TProc=procedure;
TThreadQuery = class(TThread)
private
{ Private declarations }
NewQuery:boolean;
Result:integer;
IBDatabase:TIBDatabase;
IBQuery:TIBQuery;
IBTransaction:TIBTransaction;
DataSource:TDataSource;
OnRecCount:TProc;
OnCount:TEvent;
procedure UpdateDataSet;
procedure UpdateRecordCount;
protected
procedure Execute; override;
public
RecordCount:integer;
constructor Create(BaseName:string;BaseParams:TStrings;TransParams:TStrings;DS:TDataSource;proc:TProc );
destructor Destroy;override;
procedure ExcecSql(sql:TStrings);
end;

implementation

uses RecCount;

{ TThreadQuery }

procedure TThreadQuery.ExcecSql(sql: TStrings);
begin
if Suspended then
begin
IBQuery.Close;
IBQuery.SQL.Assign(sql);
NewQuery:=true;
Resume;
end;
end;

constructor TThreadQuery.Create(BaseName: string; BaseParams,
TransParams: TStrings; DS:TDataSource;proc:TProc);
begin
inherited Create(true);

FreeOnTerminate:=false;
NewQuery:=false;

IbDatabase:=TIBDatabase.Create(nil);
IbDatabase.DatabaseName:=BaseName;
IbDatabase.LoginPrompt:=false;
IbDatabase.Params.Assign(BaseParams);

IbTransaction:=TIBTransaction.Create(nil);
IbTransaction.DefaultDatabase:=IbDatabase;
IbTransaction.Params.Assign(TransParams);


IBQuery:=TIBQuery.Create(nil);
IBQuery.Transaction:=IbTransaction;
IBQuery.Database:=IbDatabase;
DataSource:=DS;

OnCount:=TEvent.Create(nil,true,false,"");

OnRecCount:=proc;
end;

destructor TThreadQuery.Destroy;
begin
IBQuery.Close;
IBDatabase.Free;
IBTransaction.Free;
IBQuery.Free;
OnCount.Free;
inherited Destroy;
end;

procedure TThreadQuery.Execute;
var RecCountQuery:TRecCount;
begin
IBDatabase.Open;
while not terminated do
begin
if NewQuery then
begin
try
RecordCount:=-1;

RecCountQuery:=TRecCount.Create(IBDatabase.DatabaseName,IBDatabase.Params,IBTransaction.Params,IBQuery.SQL,OnCount);
IBQuery.Open;
Synchronize(UpdateDataSet);

if OnCount.WaitFor(10000)<>wrSignaled then
RecordCount:=-1
else
RecordCount:=RecCountQuery.Return;
OnCount.ResetEvent;
RecCountQuery.Destroy;

Synchronize(UpdateRecordCount);
Result:=1;
except
Result:=-1;
end;
end;

Suspend;

end;
end;

procedure TThreadQuery.UpdateDataSet;
begin
DataSource.DataSet:=IBQuery;
end;

procedure TThreadQuery.UpdateRecordCount;
begin
OnRecCount ;
end;

end.


 
RomanFromMD   (2003-02-03 19:46) [5]

unit RecCount;

interface

uses
Classes,IBDatabase,IBQuery,DB,SysUtils,SyncObjs;
type
TRecCount = class(TThread)
private
{ Private declarations }
IBDatabase:TIBDatabase;
IBQuery:TIBQuery;
IBTransaction:TIBTransaction;
OnCount:TEvent;
function ChangeSql(s:String):string;
protected
procedure Execute; override;

public
Return:smallint;
constructor Create(BaseName:string;BaseParams:TStrings;TransParams:TStrings;Sql:TStrings;Event:TEvent);
destructor Destroy;override;

end;

implementation

{ TRecCount }

function TRecCount.ChangeSql(S:string):string;
var j,i:integer;
begin
Result:=UpperCase(S);
i:=Length(Result);
if (pos("SELECT",Result)=1) then
begin
j:=Pos("FROM",Result);
if j>0 then Result:="SELECT COUNT(*) "+
Copy(Result,j-1,i);
end else
Result:="";
end;

constructor TRecCount.Create(BaseName: string; BaseParams,
TransParams: TStrings;Sql:TStrings;Event:TEvent);
begin
inherited Create(true);



IbDatabase:=TIBDatabase.Create(nil);
IbDatabase.DatabaseName:=BaseName;
IbDatabase.LoginPrompt:=false;
IbDatabase.Params.Assign(BaseParams);

IbTransaction:=TIBTransaction.Create(nil);
IbTransaction.DefaultDatabase:=IbDatabase;
IbTransaction.Params.Assign(TransParams);


IBQuery:=TIBQuery.Create(nil);
IBQuery.Transaction:=IbTransaction;
IBQuery.Database:=IbDatabase;

IBQuery.SQL.Add(ChangeSql(sql.Text));

OnCount:=Event;

Resume;
end;



destructor TRecCount.Destroy;
begin
IBDatabase.Free;
IBTransaction.Free;
IBQuery.Free;
inherited Destroy;
end;

procedure TRecCount.Execute;
begin
IBDatabase.Open;
try
IBQuery.Open;
Return:=IBQuery.Fields.Fields[0].AsInteger;
IBQuery.Close;
OnCount.SetEvent;
except
Return:=-1;
end;
end;

end.


 
RomanFromMD   (2003-02-03 19:50) [6]

Выше было описание классов
а вот так я к ним обращаюсь
....
IBQuery1:=TThreadQuery.Create(DatabaseName,DatabaseParams,TransactionParams,DataSourceVagon,OnCountVagon);

IBQuery2:=TThreadQuery.Create(DatabaseName,DatabaseParams,TransactionParams,DataSourceVagon,OnCountVagon);


...
s.text:="Select * from v1";
IBQuery1.ExcecSql(s);

s.text:="Select * from v2";
IBQuery2.ExcecSql(s);
...


 
RomanFromMD   (2003-02-03 19:53) [7]

Я заметил если поставить задержку между выполнением
IBQuery1.ExcecSql(s) и
IBQuery2.ExcecSql(s);
то вроде работает все более менее правильно.Объяснить это никак не могу. За ранее спасибо.




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

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

Наверх




Память: 0.49 MB
Время: 0.015 c
4-63893
Solod
2003-01-08 05:49
2003.02.20
---|Ветка была без названия|---


14-63735
Andrey
2003-02-03 14:07
2003.02.20
---|Ветка была без названия|---


14-63827
Ihtiandr
2003-02-04 10:25
2003.02.20
DBGrid


14-63737
Карелин Артем
2003-02-05 12:18
2003.02.20
Пить вредно?


1-63609
Новенький в Делфи
2003-02-11 13:15
2003.02.20
Как скопировать содержимое TPaintBox в TImage?