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



BeitragVerfasst: Fr 08.11.02 13:53 
Hi,

langsam gehts ans eingemachte. 8)

Weiß jemand, wie ich folgendes realisieren kann : Ändere ich z.B. einen Kunden, so soll der ja danach abgespeichert werden. Also mache ich vorsichtshalber eine Abfrage. Diese soll aber nur kommen, falls auch wirklich ein Feld geändert wurde. Da dies auch noch im Netzwerk funktionieren muß, wäre wohl die beste Methode, den Satz noch einmal kurz vor dem Abspeichern neu zu lesen und diesen mit dem Satz, der sich sozusagen noch auf dem Bildschirm befindet zu vergleichen. Ich habe da eine Prozedur gemacht, die das Byte für Byte tut.

Wenn ich den aber erneut lese sind die Änderungen futsch. Ich brauche also 2 Kopien des Datensatzes, um diese zu vergleichen. Bei Unterschieden muß ich eventuell noch zusätzlich einzelne Felder aus dem neu gelesenen Datensatz herauspicken und in den geänderten eintragen.

Jetzt habe ich gelesen, daß IB einen BDR (Back Difference Record) hat. Name ist aber ohne Gewähr :mrgreen: Verstehe ich das richtig, wäre das ungefähr, was ich brauche. Darüber ist aber nichts zu finden. Ich weiß auch nicht mehr woher ich das überhaupt weiß. Benutzt jemand sowas, oder wo könnte man Informationen darüber herkriegen ?

Gruß
Hansa
Lemmy
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 792
Erhaltene Danke: 49

Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
BeitragVerfasst: Fr 08.11.02 14:29 
Hi hansa,

grundsätzlich: Du solltest Änderungen am Datensatz direkt in der Maske erkennen, d.h. wird in einem Edit-Feld o.ä. was verändert, soll die Abfrage kommen.

zu Deiner Idee:

Da iB ja mit einer Transaktionsverwaltung ausgestattet ist kannst Du über 2 Wege an Deine Daten kommen:

1. Du öffnest eine Transaktion und holst die Daten raus, lässt sie anzeigen und schließt dann die Transaktion wieder. Wenn Du nun auf eine Änderung abprüfen willst, dann öffnest Du wieder eine Transaktion und holst die Daten und vergleichst sie diesmal. Jetzt kann aber in der Zwischenzeit schon jemand anders die Daten geändert haben (und du nicht) und Du schreibst (weil ja Unterschiede da sind) die "falschen" Daten wieder zurück.

2. Möglichkeit: Du lässt die Transaktion offen und holst Dir bei evtl. Änderungen über eine ZWEITE TIBDataSet eine weitere Kopie der Daten. Dann hast Du ne gute Chance, dass das funzt. Wobei ich aber dennoch die obere Lösung (Änderung in der Maske) empfehlen würde.

Grüße
Lemmy
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: Fr 08.11.02 15:08 
Hi
Lemmy hat folgendes geschrieben:
grundsätzlich: Du solltest Änderungen am Datensatz direkt in der Maske erkennen, d.h. wird in einem Edit-Feld o.ä. was verändert, soll die Abfrage kommen.

Stimme ich voll zu.

Lemmy hat folgendes geschrieben:
1. Du öffnest eine Transaktion und holst die Daten raus, lässt sie anzeigen und schließt dann die Transaktion wieder.

Damit sind auch deine Daten nicht mehr sichtbar, bzw. änderbar, weil die Datenmenge dabei geschlossen wird.
Bleibst du dagegen innerhalb der aktuellen Transaktion und ein anderer Benutzer hat die Daten geändert, bekommst du einen Lock auf den Datensatz und kannst ihn ebenfalls nicht mehr ändern.

Lemmy hat folgendes geschrieben:
2. Möglichkeit: Du lässt die Transaktion offen und holst Dir bei evtl. Änderungen über eine ZWEITE TIBDataSet eine weitere Kopie der Daten. Dann hast Du ne gute Chance, dass das funzt.

Damit hättest du genaus das Problem das du bei 1 beschrieben hast, weil du jetzt die bereits bestätigten Daten einer anderen Transaktion bekommen kannst.

Für mich stellt sich die ausserdem die Frage warum du unnötig das Datenaufkommen im Netz erhöhen willst. In dem Moment wo ein Feld geändert wird (Status der DataSource wechselt auf dsEdit) wird der Speichern-Button aktiviert, sonst ist er deaktiviert.

Gruss Lothar

_________________
Der BH ist für die Brust, der Plan ist für'n Ar...
Lemmy
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 792
Erhaltene Danke: 49

Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
BeitragVerfasst: Fr 08.11.02 16:43 
LCS hat folgendes geschrieben:

Damit sind auch deine Daten nicht mehr sichtbar, bzw. änderbar, weil die Datenmenge dabei geschlossen wird.


Stimmt, ich bin aber davon ausgegangen, dass in dem Fall die Daten selbst visualisiert werden. Habs aber irdgenwie vergessen zu schreiben.. :oops:

LCS hat folgendes geschrieben:

Damit hättest du genaus das Problem das du bei 1 beschrieben hast, weil du jetzt die bereits bestätigten Daten einer anderen Transaktion bekommen kannst.


Hier gings nicht darum Deadlocks zu vermeiden.... :D Wenn auch das noch dazukommt ist es wirklich am besten wie in der ersten Möglichkeit beschrieben ist: Daten holen und selbst visualisieren und Transaktion gleich wieder schließen. Das beinhaltet aber nen Haufen Aufwand. Wenn man aber das ganze objektorientiert angeht (also für den Zugriff auf die Datenbank eigene Objekte (wie z.B. TAdresse) verwenden), lässt sich der "Aufwand" für die Visualisierung zumindest teilweise wieder "aufholen" *)

LCS hat folgendes geschrieben:
In dem Moment wo ein Feld geändert wird (Status der DataSource wechselt auf dsEdit) wird der Speichern-Button aktiviert, sonst ist er deaktiviert.


Oder ganz krass (aber mein Standardvorgehen): Änderungen sind nur möglich, wenn man auf den "Bearbeiten"-Button klickt....

Grüße
Lemmy

*) dazu hat Holger Klemt im "Der Entwickler" eine dreiteilige Artikelserie veröffentlicht, die hier im Original runtergeladen werden kann:
www.dibug.de/download/oop_ek2000.zip
hansa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Fr 08.11.02 17:44 
Hi,

Lemmy hat folgendes geschrieben:

grundsätzlich: Du solltest Änderungen am Datensatz direkt in der Maske erkennen, d.h. wird in einem Edit-Feld o.ä. was verändert, soll die Abfrage kommen.


Selbst wenn ich in einem OnExit eines DBedit (und dann noch bei jedem :autsch: ) überprüfe, ob irgendwer vorher eine Änderung vorgenommen hat, weiß ich doch noch nicht WAS er geändert hat. D.h.: bei Änderung event. 4 Seiten Maske verwerfen. Merke aber, das da muß näher erläutert werden, das Bsp. ist nicht sehr gut aber nicht unmöglich (wie gesagt es geht ans Eingemachte :mrgreen: ) :

Also :

Gehe mal von einem Artikel mit Preis und letzter Verkauf (Datum) aus, wobei deer letzte Verkauf nicht von hand editiert werden soll.

1. 1. User will um 23:59 eine Art.Bez ändern, gibt die Art.Nr. ein und holt die Daten.
2. Ein zweiter will eine Rechnung schreiben und tut dasselbe.
3. 1. User speichert seine Änderung um 0:00
4. 2. User will die Rechnung um 00:01 speichern, womit das letzter Verkaufs Feld halt geändert werden müßte.

Jetzt ist die Frage : Der Artikel ist nicht mehr in dem Zustand wie er war, als der Rechnungsschreiber anfing seine Arbeit zu machen. Soweit ich weiß erzeugt IB für solche Fälle einen BDR. Das ganze hat auch was mit Multi-Generationen-Architektur oder Versioning zu tun. Aber nur indirekt.

Zitat:
Oder ganz krass (aber mein Standardvorgehen): Änderungen sind nur möglich, wenn man auf den "Bearbeiten"-Button klickt....


Genau darum geht es, was ist wenn jemand um 11:59 den Datensatz in dsEdit schickt und wegen der verlängerten Mittagspause erst um 15 Uhr wieder weitermacht ? Dadurch könnte man nicht nur einen Deadlock verursachen, sondern dafür sorgen, daß alles stillsteht.

Also ich hab das in solchen Fällen immer so gemacht, ohne Interbase :

1. Record-Lock
2. neu lesen von Platte
3. zwischenzeitlich geänderte Felder aktualisieren.
4. Speichern und Unlock.

ODER:

Änderungen verwerfen.

Das ist so was wie mit dem BDR. Es ginge aber noch folgendermaßen : letzter Bezug in eine eigene Table setzen, wahrscheinlich läufts darauf hinaus 8) . Aber dann brauche ich statt 50 wahrscheinlich 100 Tables mit Zubehör. Eine komplizierte Datei hätte dann ca. 10 Stammtables mehr.

Gruß
Hansa
Lemmy
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 792
Erhaltene Danke: 49

Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
BeitragVerfasst: Fr 08.11.02 18:01 
hansa hat folgendes geschrieben:

Also :

Gehe mal von einem Artikel mit Preis und letzter Verkauf (Datum) aus, wobei deer letzte Verkauf nicht von hand editiert werden soll.

1. 1. User will um 23:59 eine Art.Bez ändern, gibt die Art.Nr. ein und holt die Daten.
2. Ein zweiter will eine Rechnung schreiben und tut dasselbe.
3. 1. User speichert seine Änderung um 0:00
4. 2. User will die Rechnung um 00:01 speichern, womit das letzter Verkaufs Feld halt geändert werden müßte.


Prizipiell sind alle DB's bei denen Änderungen an einer Tabelle automatisch Änderungen an bestimmten Datensätze einer anderen Tabelle (also das was Du machst: Eingabe einer Rechnung wirkt sich auf die Tabelle ARtikel auf einen bestimmten Datensatz aus) hervorrufen, für DeadLocks geradezu geschaffen. Es gibt da aber nen Workaround: Du versuchst die Änderung in die Tabelle Artikel zu schreiben. Wenn das nicht geht (weil ein anderer gerade den Artikel bearbeitet), schreibst Du die Änderung in eine Update-Tabelle (z.B. Aritkel_Update) Allerdings musst Du dann bei einem erneuten Zugriff auf die Spalte "LetzterVerkauf" der Tabelle Artikel überprüfen, ob für Deinen Datensatz in der Tabelle Artikelt_Update ein Eintrag vorliegt. In dem Fall musst Du eben diesen Wert auslesen. Wenn es dann mal ruhiger wird, kann ein zusätzliches Programm diese Update-Tabelle auslesen und die Original-Tabelle auf Vordermann bringen. Ist zwar etwas komplizierter, funktioniert aber totsicher....

hansa hat folgendes geschrieben:

Genau darum geht es, was ist wenn jemand um 11:59 den Datensatz in dsEdit schickt und wegen der verlängerten Mittagspause erst um 15 Uhr wieder weitermacht ? Dadurch könnte man nicht nur einen Deadlock verursachen, sondern dafür sorgen, daß alles stillsteht.


Diesen Mitarbeiter zuerst Lynchen und anschließen fristlos entlassen.... :wink:

Das kannst Du am einfachsten erledigen, wenn Du vorgehst wie es Holger Klemt in diesem oben genannten Artikel (OOP-DB Zugriff) beschrieben hat. Dort wird die Transaktion kurz geöffnet um die Daten zu holen (beim Erzeugen des Objektes) und wenn die Daten geändert worden sind (wie Du das feststellst (Änderung in einem Edit, Klicken auf einen Button, usw. ist egal) kannst Du wieder eine Transaktion öffnen und die Daten in die DB zurückschreiben. Dann hast Du nie mehr Probleme mit einem Deadlock, außer zwei schreiben wirklich zur gleichen Zeit zurück. Das Problem, dass sich zwei Mitarbeiter gegenseitig überschreiben kann aber immer passieren, also Mitarbeiter 1 holt Daten, Mitarbeiter 2 holt Daten, beide verändern die Daten und schreiben diese wieder zurück....

hansa hat folgendes geschrieben:

letzter Bezug in eine eigene Table setzen, wahrscheinlich läufts darauf hinaus 8) . Aber dann brauche ich statt 50 wahrscheinlich 100 Tables mit Zubehör. Eine komplizierte Datei hätte dann ca. 10 Stammtables mehr.


Schau Dir vorher den Artikel an... das geht dann wirklich einfacher..... :-)


Grüße
Lemmy
hansa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Sa 09.11.02 13:10 
Hi Lemmy,
Zitat:

Schau Dir vorher den Artikel an... das geht dann wirklich einfacher.....


Holger Klemt ? IBexpert ! Das benutze ich lieber als die "richtige" IBconsole. :wink: Nur wo ist der Artikel ?

Gruß
Hansa
Lemmy
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 792
Erhaltene Danke: 49

Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
BeitragVerfasst: Mo 11.11.02 10:05 
hansa hat folgendes geschrieben:
Nur wo ist der Artikel ?


Hier:

www.dibug.de/download/oop_ek2000.zip

entpacken und dann findest Du neben ein paar Beispielen aus der EKON auch den Artikel (3 MS Word Doc)....

Grüße
Lemmy
hansa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Mo 11.11.02 10:22 
Hi Lemmy,

ich dachte schon : meint der einen Artikel aus meiner DB ? :mrgreen:

Gruß
Hansa
hansa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Di 12.11.02 21:06 
Hi,

habe den Artikel jetzt mal in Ruhe gelesen. Der ist wirklich gut, aber ich verstehe nicht so ganz worauf er hinaus will, also jetzt im Zusammenhang mit dem Thema hier. Es geht doch offenbar darum, die Tables vernünftig, bzw. gleich zu behandeln und sie in Delphi anzulegen usw. Vermute, Du willst auf die ID -1 hinaus. Was er da schreibt ist nützlich für mich, da ich immer noch nicht weiß, wie ich 3 :hair: Bool-Werte behandeln soll. Aber das ist wieder ein anderes Thema. Aber ich sehe gerade, er hat ja einen Link angegeben, wegen der begrenzten Länge des Artikels. 8) Gucke mal da rein. Außerdem hat er mir sogar gestern persönlich eine Antwort auf eine andere Frage gegeben.

Gruß
Hansa
Lemmy
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 792
Erhaltene Danke: 49

Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
BeitragVerfasst: Mi 13.11.02 08:44 
Guten Morgen,

es geht doch darum, dass Du einen Deadlock praktisch ausschließen willst. Das kannst Du nur dadurch erreichen, dass Du eine Transaktion so kurz wie möglichst öffnest, d.h. die Visualisierung der Daten von Hand vornimmst. Deshalb habe ich Dir den Artikel empfohlen, da dort dfie Daten auch "per Hand" visualisiert werden, mit dem Nebeneffekt, dass Du Objekte für den Zugriff auf die DB verwendest....

Grüße
Lemmy
hansa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Mo 23.12.02 02:38 
Hi,

was ein BDR ist, weiß anscheinend keiner. Jetzt ist mir auch noch im Zusammenhang mit einem ClientDataSet eine Delta - Property aufgefallen. Wer Mathematik kennt, weiß, daß das ein Begriff aus der Integralrechnung ist. Was unterscheidet jetzt ein DataSet von einem ClientDataSet? Da blick ich nicht durch. 8) Der BDR - Record, naja. Aber mir ist bekannt und es ist auch logisch, daß bei Daten-Änderungen im Prinzip folgende Datensätze existieren : Der ursprüngliche und der aktuelle, bei einem guten System noch eine Kopie des ursprünglichen. Wer weiß was hierzu ?

Gruß
Hansa
hansa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Mo 23.12.02 02:44 
Hi,

es geht noch um folgendes : z.B.: pro Artikel will ich ein Feld einfügen "letzter Verkauf".Dieses Feld sollte schon einem Artikel zugeordnet werden, aber von Hand nicht editierbar sein. Wenn jetzt ein anderer User den Artikel bearbeitet, soll nur dieses Feld ohne irgendwelche Abfragen geändert werden und zwar auf einen aktuellen
Wert und das automatisch.

Gruß
Hansa