Autor Beitrag
hansa
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Mo 23.09.02 21:45 
Hallo Leute,

habe eine Eingabemaske für DB-Felder. Zum Schluß soll der geänderte Datensatz dann abgespeichert werden. Die Maske soll leer sein, bis der nächste Datensatz editiert wird. D.h. Die Felder des zuvor bearbeiteten Datensatzes sollen nicht mehr auf dem Bildschirm stehen.

Wenn ich nun folgendes ausführe:

ausblenden Quelltext
1:
2:
3:
4:
5:
  if MessageDlg('Soll der Datensatz gespeichert werden ?',
    mtInformation, [mbYes, mbNo], 0) = mrYes then begin

    DataModul.KGdatenSatz.post;
    DataModul.KGdatenSatz.ClearFields


Dann kommt an der Stelle mit Clearfields die Fehlermeldung dataset not in Edit or Insert-Mode. Drehe ich die zwei Zeilen um, so würde er doch einen leeren Satz speichern, oder? :shock: . Kommentiere ich die Zeile ClearFields aus, geht zwar alles aber die Felder des vorherigen Datensatzes sind noch solange zu sehen, bis ich explizit einen aus der DB auswähle oder einen neuen anlege.

Kann man das auch anders machen? :D

Gruß
Hansa
grayfox
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 800

win98, winXP
D4 Standard; D6 Personal
BeitragVerfasst: Di 24.09.02 00:25 
hallo hansa!
ein 'clearfields' nützt dir nicht viel, da du den inhalt der datenfelder damit löscht und nicht nur die anzeige. DBEdit-Felder sind eben mit der DB verbunden und keine normalen Edit-Felder. wenn die felderer wirklich leer sein müssen (wozu eigentlich ??? ) dann häng einen leeren datensatz an, den du beim beenden des editierens wieder löscht oder mach den umweg über normale Edit-felder, die du eben händisch füllst und nach dem speichern in der Tabelle löschen darfst.
mfg, stefan
hansa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Di 24.09.02 01:12 
Hallo grayfox,

Grüße nach Österreich!

Das mit den Edit Feldern kann ich nicht machen. :cry: So gehts nicht. Das mit dem leeren Datensatz ist allerdings eine unkonventionelle Idee. :mrgreen: Hört sich gar nicht so schlecht an. Merke mir das für ähnliche Fälle.

Aber ich glaube das komische Verhalten selber erklären zu können. Das hier ist nicht der einzige Effekt.
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TKGeingabe.FormShow(Sender: TObject);
begin
  DataModul.Database.Open;
  DataModul.Transaction.StartTransaction;
  DataModul.KGdatenSatz.Open;
  Edit1.SetFocus;
end;

procedure TKGeingabe.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  DataModul.TransAction.Commit;
  DataModul.Database.Close;
end;


Habe aus Versehen anscheinend das COMMIT falsch gesetzt. Das steht bei mir im Moment bei FormClose, da ich die Sache hier aber in einer Schleife laufen lasse, kann ich nicht auf das FormClose warten. Dann könnte es solche Effekte geben.

Muß mir das ganze morgen nochmal genau ansehen. :shock:

Wenn aber jemand Erfahrungen hat, wo das COMMIT am besten ausgeführt wird, nur her damit ! :mrgreen: Der Code kommt mir sowieso irgendwie komisch vor. :twisted:

Bis dann
Hansa

@Admin: Habe von Hand [code] usw. eingeben müssen, andernfalls war alles erst am Ende des Textes. Dann hätte ich die Hälfte neu tippen müssen. Habe ich was falsch eingestellt :?: :D :P
LCS
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1305
Erhaltene Danke: 1

WIN 7, WIN 8
Delphi XE5, Delphi XE, Delphi 2007
BeitragVerfasst: Di 24.09.02 07:16 
Hi Hansa
eigentlich gibt's an dem Commit nix auszusetzen. Beim Schliessen der Form werden die Änderungen der Transaktion in die DB eingetragen. Dabei werden alle offnen Datenmengen verworfen. Wenn du nur eine Transaktion verwendest, gilt das allerdings auch für alle anderen Fenster.
Du könntest an dieser Stelle alternativ ein CommitRetaining verwenden und das Commit beim Programmende.
Das mit den leeren Feldern nach dem Post wird du IMHO nur hinkriegen, wenn du nach dem Post deine Datenmenge schliesst. Da du ja mit einem FIBDataset arbeitest und den immer auf der Basis eines Suchkriterium suchst, könntest du das Schliessen, dass du normalerweise vor dem Ändern des SelectSQL machst, hier plazieren.

Gruss Lothar

_________________
Der BH ist für die Brust, der Plan ist für'n Ar...
hansa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Di 24.09.02 12:42 
Hi Lothar,

Durch das FormClose kann doch im Extremfall folgendes passieren : Ich gebe einen ganzen Tag lang 1000 Datensätze ein, will Feierabend machen,
gerade noch die Form schließen, da fällt der Strom aus.

So wie ich es sehe wäre es sogar so, falls der Strom doch nicht ausfällt, die ersten 999 Sätze sowieso nicht in der DB wären. Oder nicht? Weiß zwar, wozu eine Transaktion gut ist, aber wie man sie am Besten in Delphi handhabt? :(

Was passiert denn eigentlich wenn ich bei dem 1000. Satz sage ROLLBACK! Dann hängen doch die 1000 Sätze in einer Transaktion. Oder? Merke, daß ich die Transaktionen noch genauer unter die Lupe nehmen muß :shock:

Bei der ursprünglichen Frage ist es so, daß es bereits funktioniert hat :mrgreen: Glaube es war so, daß (wie Lothar schreibt ) irgendwo ein close oder wie ich vermute ein Commit an der falschen Stelle steht.

Die richtige Stelle für das Commit ist meiner Meinung nach das OnExit-Event meines "speichern" Buttons. Was macht denn das CommitRetaining genau ?

Gruß
Hansa
LCS
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1305
Erhaltene Danke: 1

WIN 7, WIN 8
Delphi XE5, Delphi XE, Delphi 2007
BeitragVerfasst: Di 24.09.02 13:32 
Hi
CommitRetaining trägt die Änderungen der Transaktion ebenfalls in die Datenbank ein. Damit könnten andere User diese Änderungen sehen. Allerdings wird die Transaktion dabei nicht abgeschlossen sondern bleibt aktiv.

Gruss Lothar

_________________
Der BH ist für die Brust, der Plan ist für'n Ar...
hansa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Di 24.09.02 17:48 
Hallo Lothar,

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TKGeingabe.FormShow(Sender: TObject);
begin
  DataModul.Database.Open;
  DataModul.Transaction.StartTransaction;
  DataModul.KGdatenSatz.Open;
  Edit1.SetFocus;
end;

procedure TKGeingabe.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  DataModul.TransAction.Commit;
  DataModul.Database.Close;
end;


Also an dieser Stelle werde ich doch bestimmt Schiffbruch erleiden. :twisted: Die Form bleibt doch eventuell lange geöffnet, also auch die Transaction. Sollte man nicht die in FormClose durchgeführten Aktionen ins OnExit des speichern-Buttons verlagern ?? Vielleicht auch nur das TransAction.Commit ? Genauso wäre es doch dann sinnvoll, in dem "nicht speichern"-Button ein Rollback auszuführen. Sind aber 1000 Transaktionen offen so wird doch erst durch ein Commit alles ausgeführt, bzw. durch ein Rollback alles verworfen. Oder stehe ich doch auf dem Schlauch? :)

Experimentiere halt im Moment noch mit einfachen DS etc., aber was wäre, wenn eine Rechnung geschrieben wird, wobei der im Art-DS hinterlegte letzte VK aktualisiert wäre, dasselbe beim Kunden, der Lagerbestand wäre bereits abgebucht, damit keine nicht vorhandene Ware verkauft werden kann, sämtliche Statistiken wären bereits aktualisiert usw. usw. Und jemand merkt, die Rechnung kann so gar nicht geschrieben werden ?

Dann wäre doch wohl ein Rollback angesagt.

Gruß
Hansa
LCS
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1305
Erhaltene Danke: 1

WIN 7, WIN 8
Delphi XE5, Delphi XE, Delphi 2007
BeitragVerfasst: Di 24.09.02 18:48 
Hi
Zitat:

Also an dieser Stelle werde ich doch bestimmt Schiffbruch erleiden. Die Form bleibt doch eventuell lange geöffnet, also auch die Transaction. Sollte man nicht die in FormClose durchgeführten Aktionen ins OnExit des speichern-Buttons verlagern ?? Vielleicht auch nur das TransAction.Commit ?

Schiffbruch nicht gerade. Aber die Informationen werden solange nicht die die DB eingetragen, wie das Fenster offen ist. Und wenn der Anwender gerade Mittagspause macht? :roll:
Natürlich kannst du beim Speichern ein Commit und beim Verwerfen ein Rollback machen, aber das betrifft auch alle anderen Datenmengen dieser Transaktion. Also auch Nachschlageliste usw.
Zitat:

Sind aber 1000 Transaktionen offen so wird doch erst durch ein Commit alles ausgeführt, bzw. durch ein Rollback alles verworfen.

Eigentlich kannst du immer nur eine Transaktion aktiv haben, aber die kann 1000 Änderungen beinhalten (Gebt mir ein Haar auf dass ich es spalte :mrgreen: )
Zitat:

Und jemand merkt, die Rechnung kann so gar nicht geschrieben werden ?
Dann wäre doch wohl ein Rollback angesagt.

Genau dafür sind Transaktionen da.

Ich verfahre in der Regel so:
Solange ein Fenster offen ist, wird die Transaktion nicht abgeschlossen. Solange hat der User die Gelegenheit alles Rückgängig zu machen.
Wird das Fenster geschlossen, wird ein CommitRetaining ausgeführt.
Sind alle Fenster geschlossen (keine Datenmengen mehr in Gebrauch) wird in regelmässigen Abständen ein Commit ausgeführt um noch belegte Resourcen freizugeben.

Gruss Lothar

_________________
Der BH ist für die Brust, der Plan ist für'n Ar...
hansa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Di 24.09.02 21:01 
Hi Lothar,

Zitat:
Eigentlich kannst du immer nur eine Transaktion aktiv haben, aber die kann 1000 Änderungen beinhalten (Gebt mir ein Haar auf dass ich es spalte )


AHH ! Verstanden hast du aber trotzdem was ich sagen wollte :mrgreen:

Im Moment geht es mir aber hauptsächlich darum, erst einmal die notwendigen Stammdaten - Tabellen hinzukriegen. Das betrifft vom schreibenden Zugriff her eigentlich jeweils nur eine table. Für die Kunden brauche ich natürlich noch meine KG's u.a. (der kunde-DS hat schon eine ID_KG, au weia! Foreign Keys muß ich ja auch noch hinkriegen), aber eigentlich nur zur Anzeige/Auswahl.

Stell dir ein neues System vor, in dem erst einmal alle Kunden eingegeben werden müssen (von Hand :P ). Derjenige, der das macht wird kaum die Form nach jedem neu angelegten Kunden schließen. Eher geht es so, er gibt auf einen Schlag einen Haufen Kunden ein, ist müde und macht Feierabend, Bildschirm aus, Ende. 8)

Am nächsten Morgen will er dann alles einschalten, und drückt den Knopf an seiner Steckerleiste, wie jeden Tag, der aber rot leuchtet... Der Server hängt natürlich da auch noch dran. Natürlich hat er abends alles sauber runtergefahren, das ist doch klar. :mrgreen: Das hier ließe sich noch um Varianten steigern, auf die keiner kommt. Alles schon erlebt. Ein BlueScreen etc. reicht ja auch schon.

Die Verknüpfung (Commit usw.) mit dem FormClose ist schon plausibel, mir aber zumindest für solche Fälle (große und immer gleichbleibende Eingabemengen) zu riskant. Ich mach das lieber nach jedem Editiervorgang eines DS.

Merke, daß mir das mit den Transactions doch nicht so ganz klar ist (zumindest in der Praxis), gibt es hierüber irgendwo ein vernünftiges Tuto oder so ? Bei Interbase kommt ja auch noch das Multi-Generationen-Prinzip hinzu. :shock:

Gruß
Hansa
LCS
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1305
Erhaltene Danke: 1

WIN 7, WIN 8
Delphi XE5, Delphi XE, Delphi 2007
BeitragVerfasst: Mi 25.09.02 07:28 
Tutorial weiss ich auf die schnelle keines. Aber ich kann dir InterBase Datenbankentwicklung mit Delphi von Andreas Kosch empfehlen.

Gruss Lothar

_________________
Der BH ist für die Brust, der Plan ist für'n Ar...
hansa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Mi 25.09.02 10:43 
Hallo Lothar,

habe gestern abend noch 20 Seiten darin gelesen. :oops: Habe zu viele Bücher. :mrgreen: Der hat mir sogar selber schon einmal geantwortet. :oops:

Zitat:

OLTP

Andreas Kosch (S. 148):
...
Eine Datenbankanwendung der OLTP-Kategorie wird dadurch gekennzeichnet, daß der Anwender häufig kleine, nur kurzzeitig wirkende Transaktionen startet.
...
die Datenbank muß überwiegend neue Datensätze einfügen.


Das trifft zwar in dem Fall zu, aber nicht auf die ganze Anwendung bezogen. Brauche auch lange Abfragen. Ich les mal weiter. :roll:


Gruß
Hansa