Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Datenmodul alle Queries in einem schliessen (https://www.delphipraxis.net/211970-datenmodul-alle-queries-einem-schliessen.html)

josef-b 27. Nov 2022 17:37

Datenbank: Firebird • Version: 3.0 • Zugriff über: IBExpress

Datenmodul alle Queries in einem schliessen
 
Ich habe ein Datamodul mit vielen TIBQuery.

Nun möchte ich beim oncreate des Datamoduls alle Transactionen schliessen.

Dazu habe mir folgenden Code vorgestellt ;-)

Delphi-Quellcode:
for i := 0 to Datenmodul.ComponentCount - 1 do
  begin
  if Datenmodul.Components[i] is TIBQuery then
    begin
    AQuery := Datenmodul.Components[i] as TIBQuery;
    if Aquery.Transaction.InTransaction then AQuery.Transaction.Commit;
    end;
  end;
end;
es wird fehlerfrei compiliert, aber gleich in der ersten Zeile mit dem ComponentCount bekomme ich
eine AV Zugriffsverletzung.

Funktioniert das evtl gar nicht im Datamodul?

hoika 27. Nov 2022 18:02

AW: Datenmodul alle Queries in einem schliessen
 
Ja,
im OnCreate macht das keinen Sinn.
Die Transaktionen wurden doch noch gar nicht erzeugt,
weil es das DataModul noch gar nicht gibt ...

Uwe Raabe 27. Nov 2022 18:58

AW: Datenmodul alle Queries in einem schliessen
 
Beim OnCreate des DatenModuls ist die Variable DatenModul vermutlich noch nicht zugewiesen.

dataspider 28. Nov 2022 10:38

AW: Datenmodul alle Queries in einem schliessen
 
Ich benutze dafür lieber AfterConstruction:

Delphi-Quellcode:
type
  TDMDeinDatenModul= class(TDataModule)
  ...
  public
    procedure AfterConstruction; override;
  ...
implementation
  ...
procedure TDMDeinDatenModul.AfterConstruction;
begin
  inherited;
  // hier deinen Code
end;
Frank

BerndS 28. Nov 2022 10:44

AW: Datenmodul alle Queries in einem schliessen
 
Es würde ja schon reichen, Datenmodul wegzulassen. Self ist ja das Datenmodul, welches der Variable Datenmodul nach dem Create zugewiesen wird.
Delphi-Quellcode:
for i := 0 to ComponentCount - 1 do
begin
  if Components[i] is TIBQuery then
  begin
    AQuery := TIBQuery(Components[i]);
    if Aquery.Transaction.InTransaction then
      AQuery.Transaction.Commit;
  end;
end;

dataspider 28. Nov 2022 10:50

AW: Datenmodul alle Queries in einem schliessen
 
Ich frag mich nur, welchen Grund es geben kann, beim Create Transactions zu commiten. Hätte ich eher im BeforDestruction vermutet...

Uwe Raabe 28. Nov 2022 11:30

AW: Datenmodul alle Queries in einem schliessen
 
Zitat:

Zitat von BerndS (Beitrag 1515487)
Es würde ja schon reichen, Datenmodul wegzulassen. Self ist ja das Datenmodul, welches der Variable Datenmodul nach dem Create zugewiesen wird.

Das gilt aber nur, wenn der Eventhandler auch in dem Datenmodul liegt. Er kann aber auch in jeder anderen Objektinstanz verdrahtet sein. Dann wäre Sender die bessere Alternative, wenn auch mit einem Cast.

josef-b 28. Nov 2022 15:05

AW: Datenmodul alle Queries in einem schliessen
 
Zitat:

Zitat von dataspider (Beitrag 1515488)
Ich frag mich nur, welchen Grund es geben kann, beim Create Transactions zu commiten. Hätte ich eher im BeforDestruction vermutet...

Das möchte ich machen, weil man manchmal in der Entwicklungs-Zeit die Transaktionen offen hat, obwohl die Query geschlossen ist.

Wenn du dann Compilierst sind die immer noch offen.

Und wenn du dann die Query schliesst und bei mir ist im AfterClose der Query das Commit oder CommitRetaining beim TIBDataset, dann kommt eben am Anfang das Commit nicht...

Und dann arbeitest du teilweise mit nicht aktuellen Daten...

Deshalb möchte ich sicher sein, dass erstmal alle Transaktionen inaktiv sind.

dataspider 28. Nov 2022 15:19

AW: Datenmodul alle Queries in einem schliessen
 
Also, wenn in der Zeile "for i := 0 to Datenmodul.ComponentCount - 1" eine AV kommt, würde ich zuerst im Debugger Datamodul anzeigen lassen.
Das ist dann wahrscheinlich nil.

Frank

haentschman 28. Nov 2022 16:27

AW: Datenmodul alle Queries in einem schliessen
 
Zitat:

weil man manchmal in der Entwicklungs-Zeit die Transaktionen offen hat
...Sorry, in der Entwicklung (OI) Connection.Active = True , ist aber imho ein NoGo. :warn: :zwinker:

PS:
Ich arbeite auch mit Transaktionen. Wenn mein Programm "abschmiert" wegen Blödsinn im Quelltext, sollten damit auch die Connections geschlossen sein. Und damit sollten die Transaktionen, die zu den Connections, gehörten auch weg sein...Das regelt die Datenbank selbst. :wink:

josef-b 28. Nov 2022 18:18

AW: Datenmodul alle Queries in einem schliessen
 
Zitat:

Zitat von haentschman (Beitrag 1515536)
Zitat:

weil man manchmal in der Entwicklungs-Zeit die Transaktionen offen hat
...Sorry, in der Entwicklung (OI) Connection.Active = True , ist aber imho ein NoGo. :warn: :zwinker:

PS:
Ich arbeite auch mit Transaktionen. Wenn mein Programm "abschmiert" wegen Blödsinn im Quelltext, sollten damit auch die Connections geschlossen sein. Und damit sollten die Transaktionen, die zu den Connections, gehörten auch weg sein...Das regelt die Datenbank selbst. :wink:

Wenn du aber z.B. mit Devexpress Komponenten arbeitetest, wie das TcxGrid musst du ja mal z.B. die Felder/Spalten auslesen aus der DB, wenn Du nicht alles im Code eingeben willst....Und dann vergisst man auch mal ab und zu die Datenmenge zu schliessen...vor dem compilieren..

zur Not gehts eben mit Copy and Paste..aber ich wollte es etwas eleganter machen...

Delphi-Quellcode:
with IBQuery1 do
  begin
  if transaction.InTransaction then transaction.Commit;
  end;

with IBquery2 do
  begin
  if transaction.InTransaction then transaction.Commit;
  end;
.........

himitsu 28. Nov 2022 18:25

AW: Datenmodul alle Queries in einem schliessen
 
Connection.Active nutzen wir im Designer auch öfters, z.B. um Grids einrichten zu können.

Aber wir haben solche Properties wenigstens auf
Delphi-Quellcode:
stored False
gesetzt und Dergleichen, damit es nicht ins kompilierte Programm durchrauscht.



Wir haben nahrzu alle Kompnenten abgeleitet, für eigene Erweiterungen, solche Anpassungen und zentrale Bugfixes.

dataspider 28. Nov 2022 19:11

AW: Datenmodul alle Queries in einem schliessen
 
Nur ein Lösungsansatz:

Das Datenmodul
Delphi-Quellcode:
unit DM_Datenmodul;

interface

uses
  System.SysUtils, System.Classes, Dm.Helper{helper - CommitAllTransactions};

type
  TDatenModul = class(TDataModule)
  public
    procedure AfterConstruction; override;
  end;

var
  Datenmodul: TDatenModul;

implementation

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

{Hier sind alle Objekte erzeugt}
procedure TDatenModul.AfterConstruction;
begin
  inherited;
  CommitAllTransactions;
end;

end.

Eigene unit für die helper class
Delphi-Quellcode:
unit Dm.Helper;

interface

uses
  System.Classes, IBX.KeineAhnung;

type
  TDataModuleHelper = class helper for TDataModule
  public
    procedure CommitAllTransactions;
  end;

implementation

procedure TDataModuleHelper.CommitAllTransactions;
Var
  I: Integer;
  AQuery: TIBQuery;
begin
  for I := 0 to ComponentCount - 1 do
  begin
    if (Components[i] is TIBQuery) then
    begin
      AQuery := (Components[i] as TIBQuery);
      if AQuery.Transaction.InTransaction then
        AQuery.Transaction.Commit;
    end;
  end;
end;

end.
Damit kannst du das in allen Datenmodulen verwenden...

TBx 29. Nov 2022 06:13

AW: Datenmodul alle Queries in einem schliessen
 
Ich mache sowas im Loaded der Connection. Abfragen, ob cssdesigning im Componentstate, wenn nicht, dann das Connected auf False.

Sollte sich auch im Loaded des Datamodule machen lassen.

MyRealName 29. Nov 2022 09:37

AW: Datenmodul alle Queries in einem schliessen
 
Ich denke, die IBConnection hat eine Property.. sowas wie DesignTimeConnected oder so, da ging es wohl darum, dass man zur Designzeit die connection und die Transaktionen offen haben kann, aber in Runtime wird sie nicht geöffnet. Zumindest UniConnection hat sowas wohl...

EDIT: Sehe gerade, dass IBQuery ja nicht zu IBDAC gehört, die heissen TIBCQuery... von daher geht das dann wohl eher nicht...

josef-b 29. Nov 2022 10:04

AW: Datenmodul alle Queries in einem schliessen
 
Zitat:

Zitat von dataspider (Beitrag 1515549)
Nur ein Lösungsansatz:

Das Datenmodul
Delphi-Quellcode:
unit DM_Datenmodul;

interface

uses
  System.SysUtils, System.Classes, Dm.Helper{helper - CommitAllTransactions};

type
  TDatenModul = class(TDataModule)
  public
    procedure AfterConstruction; override;
  end;

var
  Datenmodul: TDatenModul;

implementation

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

{Hier sind alle Objekte erzeugt}
procedure TDatenModul.AfterConstruction;
begin
  inherited;
  CommitAllTransactions;
end;

end.

Eigene unit für die helper class
Delphi-Quellcode:
unit Dm.Helper;

interface

uses
  System.Classes, IBX.KeineAhnung;

type
  TDataModuleHelper = class helper for TDataModule
  public
    procedure CommitAllTransactions;
  end;

implementation

procedure TDataModuleHelper.CommitAllTransactions;
Var
  I: Integer;
  AQuery: TIBQuery;
begin
  for I := 0 to ComponentCount - 1 do
  begin
    if (Components[i] is TIBQuery) then
    begin
      AQuery := (Components[i] as TIBQuery);
      if AQuery.Transaction.InTransaction then
        AQuery.Transaction.Commit;
    end;
  end;
end;

end.
Damit kannst du das in allen Datenmodulen verwenden...

Ich habe das jetzt genauso gemacht. Läuft prima. Vielen Dank dafür..


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:11 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-2025 by Thomas Breitkreuz