Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Zeos Query - too many connections (https://www.delphipraxis.net/118997-zeos-query-too-many-connections.html)

bl3nder 19. Aug 2008 10:15

Datenbank: mysql • Version: 4.1 • Zugriff über: zeos

Zeos Query - too many connections
 
Hallo,

Ich habe eine Klasse TDatabase in der sich folgendes befindet

Delphi-Quellcode:
  TDatabase = class(TObject)
  private
    FWQuery : TZQuery;
    FDQuery : TZQuery;
    FCQuery : TZQuery;
    FMQuery : TZQuery;
    FSqlConnection : TZConnection;
  public
    constructor Create();
//...
Der Konstruktor dazu sieht so aus:
Delphi-Quellcode:
constructor TDatabase.Create();
begin
  FSqlConnection := TZConnection.Create(FSqlConnection);
  FSqlConnection.HostName := '//'; //Server
  FSqlConnection.User := '//'; //Benutzername
  FSqlConnection.Password := '//'; //Passwort
  FSqlConnection.Database := '//'; //Name der Datenbank
  FSqlConnection.Protocol := 'mysql-4.1';
  FSqlConnection.Port := 3306;

  FWQuery := TZQuery.Create(FWQuery);
  FWQuery.Connection := FSqlConnection;
  FDQuery := TZQuery.Create(FDQuery);
  FDQuery.Connection := FSqlConnection;
  FCQuery := TZQuery.Create(FCQuery);
  FCQuery.Connection := FSqlConnection;
  FMQuery := TZQuery.Create(FMQuery);
  FMQuery.Connection := FSqlConnection;
end;


Nun benutze ich in einer Kind-Klasse in einer Funktion das FCQuery und während FCQuery noch offen ist wird in der selben Funktion noch das FDQuery benutzt. Wenn die Abfragen ausgelesen wurden versuche ich immer die Queries zu schließen und zu zerstören.

Delphi-Quellcode:
FCQuery.Close;

  FCQuery.SQL.Text := 'SELECT';
    FCQuery.SQL.Add('..............etc');

  FCQuery.Open;

  while not FCQuery.EOF do
  begin
    FMyStatus := FCQuery.FieldByName('Status').AsString;
    // etc


    if (...) then
      begin
      //...    
        FDList := FMyDSearch.DBSearch('vague',FMyDCriteria); // <-------- Ruft eine Funktion auf in der FDQuery in gleicher Weiße benutzt wird wie FCQuery in dieser Funktion
      //...
      end;

  //...

  FCQuery.Close;
  FCQuery.Destroy;
  //...

Obwohl ich die Queries am Ende immer zerstöre und meine Datenbank 100 Connections zur gleichen Zeit zulässt, kommt der SQL Fehler, dass "too many connections" vorhanden sind.

Vielleicht kann mir jemand sagen wie ich die Zquery richtig disconnecte ?

Bernhard Geyer 19. Aug 2008 10:26

Re: Zeos Query - too many connections
 
1, Ich sehe in deinem Code das du immer FCQuery zerstörst. Die erzeugung erfolgt nur im Konstruktor
2, Rufe Destroy nicht direkt auf. Hiefür ist Free zuständig.
3, Binde mal FastMM in deinem Code ein um schnellere Rückmeldung über Speicherlücken zu bekommen.

bl3nder 19. Aug 2008 10:41

Re: Zeos Query - too many connections
 
zu 1,
Die Funktion ist eine Funktion einer Kinderklasse von TDatabase, sprich beim Erstellen der Instanz der Kinderklasse rufe ich ja den Konstruktor auf und somit ein neues TZQuery.
Ich hab auch grad versucht die Instanz nach dem Gebrauch wieder zu zerstören, sodass die Queries alle verlorengehen, aber hilft auch nichts, gleicher Fehler.

zu 2,
Hmm ok aber ändert nichts soweit.

Bernhard Geyer 19. Aug 2008 10:58

Re: Zeos Query - too many connections
 
zu 1.

Du erzeugst die Queries im Konstruktor und gibst sie in einer Methode frei. Und wenn jetzt die Methode ein 2tes Mal für die gleiche Instanz aufgerufen wird?

bl3nder 19. Aug 2008 11:05

Re: Zeos Query - too many connections
 
Die Instanz wird einen einmaligen Aufruf erzeugt (und kann dann zerstoert werden eigentlich).
Ich denk aber nicht, dass das was mit den "too many connections" zu tun hat. Ich hab ja eher das Problem, dass die Instanzen noch vorhanden sind als dass sie mir fehlen

Bernhard Geyer 19. Aug 2008 11:07

Re: Zeos Query - too many connections
 
Dann häng doch mal FastMM rein um zu sehen ob es nicht komplett an einer anderen Stelle liegt.

bl3nder 19. Aug 2008 11:08

Re: Zeos Query - too many connections
 
Jo hab ich, find blos die komische log datei nicht ^^

Bernhard Geyer 19. Aug 2008 11:12

Re: Zeos Query - too many connections
 
Wennst du alles korrekt (Compilerschalter+Defines) machst liegt die parallel zur Exe.

bl3nder 19. Aug 2008 11:34

Re: Zeos Query - too many connections
 
Ja die Logdatei wird mega groß und ich muss das Programm abbrechen sonst hört er wohl garnicht mehr auf in die Log datei reinzuschreiben. Irgendwie bau ich mist mit meinem Objekten :/

Bernhard Geyer 19. Aug 2008 11:35

Re: Zeos Query - too many connections
 
Zitat:

Zitat von bl3nder
Ja die Logdatei wird mega groß und ich muss das Programm abbrechen sonst hört er wohl garnicht mehr auf in die Log datei reinzuschreiben. Irgendwie bau ich mist mit meinem Objekten :/

Schaut so aus. Du solltest auch TD32-Debuginfos aktiv haben sonst wirst du nicht so glücklich mit der Logdatei.

bl3nder 19. Aug 2008 11:56

Re: Zeos Query - too many connections
 
Also hier mal zur Erklaerung, vielleicht kann man den Fehler so finden:


Habe 2 Units Model.pas und Model_Database.pas



In Model.pas habe ich folgende Klassen:

Delphi-Quellcode:

  TAttributes = class(TObject)
  private
  public
  end;

  TMain = class(TObject)
  private
  public
    function DBSearch(Criteria: TAttributes): TObjectList; Virtual; Abstract;
    function DBCreate(): TZQuery; Virtual; Abstract;
    function DBEdit(): TZQuery; Virtual; Abstract;
    function DBDelete(): TZQuery; Virtual; Abstract;
  end;





  { ---- Attributes ---- }

  TDockingstationAttributes = class(TAttributes)
  private
    FComment: String;
    FFabricant: String;
    FID: Integer;
    //..
  public
    function GetComment: String;
    function GetFabricant: String;
    function GetID: Integer;
   //...
    procedure SetComment(Comment: String);
    procedure SetFabricant(Fabricant: String);
    procedure SetID(ID: Integer);
    //...
  end;
  { ---- /Attributes ---- }


  { ---- Main ---- }
  TDockingstation = class(TMain)
  private
    FAttributes : TDockingstationAttributes;
  public
    constructor Create();

    function GetAttributes(): TDockingstationAttributes;

    procedure SetAttributes(Comment: String='';Fabricant: String='';
      ID: Integer=0; ...);

  end;

  { ---- /Main ---- }


  { ---- Search ---- }

  TDockingstationSearch = class(TMain)
  private
  public
    function DBSearch(Modus: String; Criteria: TDockingstationAttributes)
      : TObjectList; Overload;
  end;

  { ---- /Search ---- }





  { ---- Attributes ---- }


  TComputerAttributes = class(TAttributes)
  private
    //..
    FComment: String;
    //..
    FGraphicCard: String;
  //..
    FDockingstation: TDockingstation; // <-- Computer enthaelt dockingstation objekt
  public
  //..get/set
  end;

  { ---- /Attributes ---- }


  { ---- Main ---- }

  TComputer = class(TMain)
  private
    FAttributes: TComputerAttributes;
  public
    constructor Create();

    function GetAttributes(): TComputerAttributes;

    procedure SetAttributes(Comment: String='';...GraphicCard: String='';...);

  end;

  { ---- /Main ---- }


  { ---- Search ---- }

  TComputerSearch = class(TMain)
  private
  public
    function DBSearch(Modus: String; Criteria: TComputerAttributes): TObjectList; Overload;
  end;

  { ---- /Search ---- }


implementation

//............


function TDockingstationSearch.DBSearch(Modus: String;
  Criteria: TDockingstationAttributes): TObjectList;
var
FMdbDsSearch: Model_Database.TDockingstationSearch;
FWsList: TObjectList;
begin
  FWsList := TObjectList.Create;
  FMdbDsSearch := Model_Database.TDockingstationSearch.Create;

  FWsList := FMdbDsSearch.DBSearch(Modus,Criteria);

  Result := FWsList;
end;


//................

function TComputerSearch.DBSearch(Modus: String; Criteria: TComputerAttributes)
  : TObjectList;
var
FMdbCSearch: Model_Database.TComputerSearch;
FCList: TObjectList;
begin
  FCList := TObjectList.Create;
  FMdbCSearch := Model_Database.TComputerSearch.Create;

  FCList := FMdbCSearch.DBSearch(Modus,Criteria);
  Result := FCList;
end;

//..










In Model_Database.pas steht folgendes:


Delphi-Quellcode:
  TDatabase = class(TObject)
  private
    FWQuery : TZQuery;
    FDQuery : TZQuery;
    FCQuery : TZQuery;
    FMQuery : TZQuery;
    FSqlConnection : TZConnection;
  public
    constructor Create();

    function DBSearch(Criteria: Model.TAttributes)
      : TObjectList; virtual; abstract;
    procedure DBCreate(); virtual; abstract;
    procedure DBEdit(); virtual; abstract;
    procedure DBDelete(); virtual; abstract;
  end;




  TDockingstationSearch = class(TDatabase)
  private
  public
    function DBSearch(Modus: String; Criteria: Model.TDockingstationAttributes)
      : TObjectList; Overload;
  end;

  TComputerSearch = class(TDatabase)
  private
  public
    function DBSearch(Modus: String; Criteria: Model.TComputerAttributes)
      : TObjectList; Overload;
  end;

implementation




constructor TDatabase.Create();
begin
  FSqlConnection := TZConnection.Create(FSqlConnection);
  FSqlConnection.HostName := ''; //Server
  FSqlConnection.User := ''; //Benutzername
  FSqlConnection.Password := ''; //Passwort
  FSqlConnection.Database := ''; //Name der Datenbank
  FSqlConnection.Protocol := 'mysql-4.1';
  FSqlConnection.Port := 3306;


  FDQuery := TZQuery.Create(FDQuery);
  FDQuery.Connection := FSqlConnection;
  FCQuery := TZQuery.Create(FCQuery);
  FCQuery.Connection := FSqlConnection;

end;





function TDockingstationSearch.DBSearch(Modus: String;
  Criteria: Model.TDockingstationAttributes): TObjectList;
var
FDSList: TObjectList;
I: Integer;
FEqual1,FEqual2 : String;
FMyDockingstation: Model.TDockingstation;
begin
  FDSList := TObjectList.Create;
  FMyDockingstation := Model.TDockingstation.Create;

 
//...
  // Search in the database for dockingstations by using the criteria
  FDQuery.Close;

  FDQuery.SQL.Text := 'SELECT * FROM Dockingstation';
  FDQuery.SQL.Add(' WHERE (1=1');
//...
  FDQuery.SQL.Add(')');
  FDQuery.Open;

  while not FDQuery.EOF do
  begin
    // Use search result to create a new dockingstation object
    FMyDockingstation.SetAttributes('','',
      FDQuery.FieldByName('DockingstationID').AsInteger,'',
       );

    // Add dockingstation to a list of dockingstation ojects
    FDSList.Add(FMyDockingstation);

    FDQuery.Next;
  end;

  FDQuery.Free;
  Result := FDSList;

end;


function TComputerSearch.DBSearch(Modus: String;
  Criteria: Model.TComputerAttributes): TObjectList;
var
//..

begin
  //..

  FCList := TObjectList.Create;

//..

  // Search in the database for computers by using the criteria
  FCQuery.Close;

  FCQuery.SQL.Text := 'SELECT';
  FCQuery.SQL.Add('....');
//...
  FCQuery.Open;

  while not FCQuery.EOF do
  begin
    FMyComputer := Model.TComputer.Create;

    // Use search result to create a new computer object
    FMyID := FCQuery.FieldByName('RechnerID').AsInteger;

   
    FMyComment := FCQuery.FieldByName('Bemerkungen').AsString;
    FMyGraphicCard := FCQuery.FieldByName('Grafikkarte').AsString;
    //...

 



// HIER KOENNTE DER FEHLER LIEGEN WEIL ICH HIER WIEDER EINE DOCKINGSTATIONSEARCH ERZEUGE UND DAS GANZE IN DER GROSSEN WHILE SCHLEIFE VOM FCSQLQUERY ---------------------

  if (FCQuery.FieldByName('DockingstationID').AsInteger > 0) then
      begin
        FMyDSearch := TDockingstationSearch.Create;
        FMyDCriteria := TDockingstationAttributes.Create;
       
        // Search for the dockingstation that is used by the computer
        FMyDCriteria.SetID(
          FCQuery.FieldByName('DockingstationID').AsInteger);
       
        FDList := FMyDSearch.DBSearch('vague',FMyDCriteria);
       


        // Create the dockingstation object for the computer object
        FMyDockingstation := FDList[0] as Model.TDockingstation;
     
      end;
 
//---------------------



    // Set all the information of the computer object
    FMyComputer.SetAttributes(...,FMyComment,...,FMyGraphicCard,.., FMyDockingstation...);

    // Add computer object to a list of computer ojects
    FCList.Add(FMyComputer);

    FCQuery.Next;
  end;


  FCQuery.Free;
  Result := FCList;

end;

bl3nder 19. Aug 2008 11:57

Re: Zeos Query - too many connections
 
Zitat:

Zitat von Bernhard Geyer
Zitat:

Zitat von bl3nder
Ja die Logdatei wird mega groß und ich muss das Programm abbrechen sonst hört er wohl garnicht mehr auf in die Log datei reinzuschreiben. Irgendwie bau ich mist mit meinem Objekten :/

Schaut so aus. Du solltest auch TD32-Debuginfos aktiv haben sonst wirst du nicht so glücklich mit der Logdatei.

Wo und wie stell ich das ein ? Finde in FastMM4Options.exe dazu nichts.

Bernhard Geyer 19. Aug 2008 12:04

Re: Zeos Query - too many connections
 
Zitat:

Zitat von bl3nder
Wo und wie stell ich das ein ? Finde in FastMM4Options.exe dazu nichts.

In den Projektoptionen, Reiterseite Linker.

bl3nder 19. Aug 2008 12:12

Re: Zeos Query - too many connections
 
Wird trotzdem eine sehr große Logdatei.. Ka ob es Sinn macht die zu posten

Bernhard Geyer 19. Aug 2008 12:16

Re: Zeos Query - too many connections
 
Zitat:

Zitat von bl3nder
Wird trotzdem eine sehr große Logdatei.. Ka ob es Sinn macht die zu posten

Es macht Sinn das du diese verstehst und deine Fehler behebst.

bl3nder 19. Aug 2008 12:19

Re: Zeos Query - too many connections
 
Hmm wie genau soll ich bitte sowas verstehen ?


Zitat:

...
--------------------------------2008/8/19 11:31:02--------------------------------
A memory block has been leaked. The size is: 20

Stack trace of when this block was allocated (return addresses):
403086
403F97
407059
40435E
577439
40709B
406FDC
579B39
5820FD
57D08E

The block is currently used for an object of class: TZVariablesList

The allocation number is: 455821

Current memory dump of 256 bytes starting at pointer address 7EDC02E0:
C4 73 57 00 01 00 00 00 19 12 40 00 70 03 DC 7E 20 73 57 00 A7 03 3C 7E 00 00 00 00 80 F6 DB 7E
00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 8E F4 06 00 86 30 40 00 97 3F 40 00 5E 43 40 00
46 D9 42 00 59 70 40 00 5E 43 40 00 49 74 57 00 39 9B 57 00 FD 20 58 00 8E D0 57 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 14 00 00 00 00 00 00 00 26 39 C6 81 4C D8 42 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 D9 C6 39 7E 00 00 00 00 80 F6 DB 7E 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00
8F F4 06 00 86 30 40 00 97 3F 40 00 59 70 40 00 5E 43 40 00 D9 50 57 00 9B 70 40 00 DC 6F 40 00
56 9B 57 00 FD 20 58 00 8E D0 57 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Ä s W . . . . . . . @ . p . Ü ~ s W . § . < ~ . . . . € ö Û ~
. . . . . . . . ÿ ÿ ÿ ÿ . . . . Ž ô . . † 0 @ . — ? @ . ^ C @ .
F Ù B . Y p @ . ^ C @ . I t W . 9 › W . ý X . Ž Ð W . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . & 9 Æ L Ø B . . . . . . . . . . . . .
. . . . Ù Æ 9 ~ . . . . € ö Û ~ . . . . . . . . ÿ ÿ ÿ ÿ . . . .
ô . . † 0 @ . — ? @ . Y p @ . ^ C @ . Ù P W . › p @ . Ü o @ .
V › W . ý X . Ž Ð W . . . . . . . . . . . . . . . . . . . . .

...

Bernhard Geyer 19. Aug 2008 12:31

Re: Zeos Query - too many connections
 
Zitat:

Zitat von bl3nder
Hmm wie genau soll ich bitte sowas verstehen ?

TD32-Debuginfos aktivieren und projekt erzeugen. Compilieren aktualisiert nur geänderte Units.

bl3nder 19. Aug 2008 12:42

Re: Zeos Query - too many connections
 
Beim Erzeugen wird keine Logdatei erstellt :gruebel:

Bernhard Geyer 19. Aug 2008 13:29

Re: Zeos Query - too many connections
 
Du mußt das Projekt erzeugen damit wirklich für jede Unit TD32-Debuginfos vorhanden sind und du statt Speicheradressen Funktions/Methodennamen bekommst.

bl3nder 19. Aug 2008 13:57

Re: Zeos Query - too many connections
 
Hmm wenn ich das Projekte erzeuge dann bekomme ich aber kein neues LOG file, welches ich ja parallel zur .exe finden muesste.

Sry aber ka was ich falsch mache

Bernhard Geyer 19. Aug 2008 14:00

Re: Zeos Query - too many connections
 
Die Logdatei wird ja nur als Ergebnis eines Programmlaufs erzeugt. Beim kompilieren kann FastMM nix herausfinden da es ja der Speichermanager der laufenden Anwendung wird.

bl3nder 19. Aug 2008 14:03

Re: Zeos Query - too many connections
 
Und wie genau soll ich dann die Log datei lesen, wenn sie garnicht erstellt wird ?

bl3nder 19. Aug 2008 14:25

Re: Zeos Query - too many connections
 
Also das ganze FastMM hat mir bisher nicht weitergeholfen.

Ich habe eine Lösung gefunden, allerdings dauert eine Datenbankabfrage laenger als normal, aber immerhin laeuft es so

Delphi-Quellcode:
procedure TDatabase.Disconnect;
begin
  FSqlConnection.Disconnect;
end;

//..





//..
  while not FCQuery.EOF do
begin
//..
    if (FCQuery.FieldByName('DockingstationID').AsInteger > 0) then
      begin
        FMyDSearch := TDockingstationSearch.Create;
        FMyDCriteria := TDockingstationAttributes.Create;
        // Search for the dockingstation that is used by the computer
        FMyDCriteria.SetID(
          FCQuery.FieldByName('DockingstationID').AsInteger);
        FDList := FMyDSearch.DBSearch('vague',FMyDCriteria);
        // Create the dockingstation object for the computer object
        FMyDockingstation := FDList[0] as Model.TDockingstation;

        FMyDSearch.Disconnect;
        FMyDSearch.Free;
      end;
end;
//..

FMyDSearch.Disconnect; ..


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:43 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz