Page 1 of 1

Using Zeos in multithread application

Posted: 14.05.2007, 11:51
by sabri.arslan
hello,
i am writing multithreading app in delphi, my each thread have a tzconnection, i am using common procedures for queries and zdataset(for ,while loops),
each procedure using connection param and quering on connection. on simple execsql queries i have no problem but when i need datasets for while loops i have giving access violations. i have tried criticial secitons but i don't success.

i send a few code blocks. please help me?
thank you.

Code: Select all

{umain.pas}
type
 TPrnInfo=packed record
 Adid:string;
 Addid:string;
 Printype:string;
 Paramater:integer;
 Userid:string;
 Username:string;
 Masano:string;
 Spoolid:string;
 Printer:string;
 printerID:string;
end;

type
 TThreadController=class(TThread)
 private
  fPrintCount:integer;
  fPrinterID,fPrinter:string;
 protected
  procedure Execute;override;
  procedure YazdirmaBaslat;
 public
  yazici:array of TPrnInfo;
  fConnection:TZConnection;
  property PrinterID:string read fPrinterID write fPrinterID;
  property Printer:string read fPrinter write fPrinter;
  property PrintCount:integer read fPrintCount;
end;

{......}

procedure TThreadController.Execute;
var
 sqlt,prn,ykodu:string;
 i,j:integer;
 plist:tstringlist;
 prl:array of TPrnInfo;
 q:TZQuery;
begin
try
 plist:=TStringList.create;
 fConnection:=OpenConnection('localhost','ibempos','ibempos',3306); 
 while not Self.Terminated do
 begin
   sqlt:='select kodu from posyazicilar where id='+quotedstr(fPrinterID);
   ykodu:=TekAlanOku(sqlt,'kodu');
   sqlt:='select ID,PRINTYPE,PARAMETER,ADID,ADDID,MASANO,PDID,'+
         ' USERID,USERNAME,YAZDIRILDI,YAZICIKODU,ROW_TIME,'+
         ' (select YAZICIYOLU from posyazicilar where kodu=yazicikodu) as printer,'+
         ' (select id from posyazicilar where kodu=yazicikodu) as printerid'+
         ' from posprintspool where yazdirildi=0 and'+
         ' (select MAKINAADI from posyazicilar where kodu=yazicikodu)='+
         quotedstr(mname)+' and YAZICIKODU='+
         quotedstr(ykodu)+' order by printer';
   try
    q:=openquery(sqlt,false,fConnection);
    if q.RecordCount>0 then
    begin
     for i:=0 to q.RecordCount-1 do
     begin
       setlength(yazici,length(yazici)+1);
       yazici[length(yazici)].Printer := q.FieldByName('printer').AsString;
       yazici[length(yazici)].printerID:= q.FieldByName('printerid').AsString;
       yazici[length(yazici)].Adid:= q.FieldByName('adid').AsString;
       yazici[length(yazici)].Addid:= q.FieldByName('addid').AsString;
       yazici[length(yazici)].Printype:= q.FieldByName('printype').AsString;
       yazici[length(yazici)].Userid:= q.FieldByName('userid').AsString;
       yazici[length(yazici)].Username:= q.FieldByName('username').AsString;
       yazici[length(yazici)].Masano:= q.FieldByName('masano').AsString;
       yazici[length(yazici)].Spoolid:= q.FieldByName('id').AsString;
       yazici[length(yazici)].Paramater:= q.FieldByName('parameter').AsInteger;
       q.RecNo:=i+2;
     end;
    end;
   finally
    q.Close;
    FreeAndNil(q);
   end;
   YazdirmaBaslat;
   Sleep(1000);
 end;
finally
 fConnection.Disconnect;
 FreeAndNil(fConnection);
 FreeAndNil(plist);
end;
end;

procedure TThreadController.YazdirmaBaslat;
var
 i,yazdirildi:integer;
 sqlt:string;
begin
  if length(yazici)>0 then
  begin
   for i:=Low(yazici) to High(yazici) do
   begin
    sqlt:='select yazdirildi from posprintspool where id='+quotedstr(yazici[i].Spoolid);
    yazdirildi:=strtointdef(tekalanoku(sqlt,'yazdirildi',fConnection),0);
    if yazdirildi=0 then
    begin
     sqlt:='update posprintspool set yazdirildi=-1 where id='+
       quotedstr(yazici[i].Spoolid);
     ExecQuery(sqlt,fConnection);
     if yazici[i].Printype='ADISYON' then
      AdPrint(yazici[i].Adid,yazici[i].Paramater,fConnection)
     else if yazici[i].Printype='SIPARIS' then
      PrintSiparis(yazici[i].Adid,yazici[i].Addid,yazici[i].Userid,yazici[i].Username,now,fConnection);
     inc(fPrintCount);
    end;
   end;
  end;
end;

{ucommon.pas}
function OpenConnection(shost,suser,pass:string;iport:integer):TZConnection;
begin
 result:=TZConnection.Create(nil);
 with result do
 begin
  HostName:=shost;
  User:=suser;
  Password:=pass;
  port:=iPort;
  Protocol:='mysql-4.1';
  database:='yenionburo';
  catalog:='yenionburo';
  Connect;
 end;
end;

//this functions running with no errors but when i use this dataset 
// recordcount running, when use "while not eof do" nothing loops
// and fieldbyname('field').asstring give access violation
function OpenQuery(sqlt:string;edit:boolean=false;conn:TZConnection=nil):TZQuery;
begin
try
 result:=TZQuery.Create(nil);
 if conn<>nil then
  result.Connection:=conn
 else
  result.Connection:=OpenConnection('localhost','ibempos','ibempos',3306);
 result.ParamCheck:=false;
 result.ReadOnly:=edit;
 result.SQL.Text:=sqlt;
 result.Open;
 result.FieldDefs.Update;
 result.FieldList.Update;
finally

end;
end;

//this functions running with no errors
function TekAlanOku(const sqlt,Alan:string;conn:TZConnection=nil):string;
var
 q:TZQuery;
begin
try
 q:=OpenQuery(sqlt,false,conn);
 if q.recordcount>0 then
  result := q.fieldbyname(alan).AsString
 else
  result:='';
 q.close;
finally
 if conn<>nil then
 begin
  q.Connection.Disconnect;
  q.Connection.Free;
  q.Connection:=nil;
 end;
 FreeAndNil(q);
end;
end;

//this functions running with no errors
function ExecQuery(const sqlt:string;conn:TZConnection=nil):boolean;
var
 t:tzreadonlyquery;
begin
 result:=false;
 try
  try
   t:=tzreadonlyquery.Create(application);
   if conn<>nil then
    t.Connection:=conn
   else
    t.Connection:=OpenConnection('localhost','ibempos','ibempos',3306);
   t.ParamCheck:=false;
   t.SQL.Text:=sqlt;
   t.ExecSQL;
   result:=true;
  finally
   if conn=nil then
   begin
    t.Connection.Disconnect;
    t.Connection.Free;
    t.Connection:=nil;
   end;
   freeandnil(t);
  end;
 except
  result:=false;
 end;
end;
email: sabri.arslan [at] gmail.com

Code: Select all

[code][php]

Re: Using Zeos in multithread application

Posted: 22.05.2007, 13:54
by xtra

Code: Select all

[...]
     for i:=0 to q.RecordCount-1 do
     begin
[...]
       q.RecNo:=i+2;
     end;
    end;
   finally
    q.Close;
    FreeAndNil(q);
   end;
   YazdirmaBaslat;
   Sleep(1000);
 end;
finally
 fConnection.Disconnect;
 FreeAndNil(fConnection);
 FreeAndNil(plist);
end;
end;
[...]
Are you sure that this is correct:
q.RecNo:=i+2;
IMO you are running over the last entry.
You might want to do:
for i:=0 to ((q.RecordCount-1) div 2) do

Just a shot in the blue.