Version 6.0
Eine Transaktion führt hintereinander Operationen aus, die Sie jederzeit komplett wieder rückgängig machen können. Die logische Datenintegrität wird dabei gewahrt. Eine Transaktion wird erst in der Datenbank gesichert, wenn die Transaktion bestätigt wird. Änderungen werden nicht gesichert, wenn eine Transaktion nicht abgeschlossen ist, weil sie entweder abgebrochen oder durch ein von außen kommendes Ereignis unterbrochen wird.
Während einer Transaktion werden alle Änderungen in der Datenbank innerhalb eines Prozesses lokal in einem temporären Speicher gesichert. Wird die Transaktion mit VALIDATE TRANSACTION bestätigt, werden die Änderungen dauerhaft gesichert. Wird die Transaktion mit CANCEL TRANSACTION abgebrochen, werden die Änderungen nicht gesichert.
Da Transaktionen mit temporären Datensatzadressen arbeiten, ist die Auswahl für jede Tabelle des aktuellen Prozesses nach Bestätigen oder Abbrechen der Transaktion leer. Verwenden Sie deshalb temporäre Auswahlen innerhalb einer Transaktion mit der nötigen Vorsicht, denn diese können unter Umständen inkorrekte Datensatzadressen enthalten. Eine temporäre Auswahl kann z.B. die Adresse eines gelöschten Datensatzes enthalten oder die temporäre Adresse eines Datensatzes, der während der Transaktion hinzugefügt wurde. Lassen Sie auch bei Mengen die nötige Vorsicht walten, das sie auf Bit-Tabellen mit Datensatzadressen basieren.
Folgende Befehle verwenden Datensatznummern verwenden Sie diese nicht in einer Transaktion:
Beispiele
In diesem Beispiel ist die Datenbank ein einfaches Rechnungssystem. Die Rechnungszeilen werden in einer Tabelle [Invoice Lines] gespeichert, die über die Felder [Invoices]Invoice ID und [Invoice Lines]Invoice ID mit der Tabelle [Invoices] verknüpft ist. Beim Hinzufügen einer Rechnung wird mit der Funktion Sequence number eine einmalige Kennung berechnet. Die Verknüpfung zwischen [Invoices] und [Invoice Lines] ist eine automatische Eine-zu-Viele Verknüpfung. Im Dialogfenster Verknüpfungseigenschaften ist das Ankreuzfeld Automatische Zuweisung des verknüpften Wertes aktiviert.
Die Verknüpfung zwischen [Invoice Lines] und [Parts] ist manuell.
Gibt ein Benutzer eine Rechnung ein, werden folgende Schritte ausgeführt:
In der Tabelle [Invoices] wird ein Datensatz hinzugefügt.
In der Tabelle [Invoice Lines] werden mehrere Datensätze hinzugefügt.
Das Datenfeld [Parts]In Warehouse wird für jeden in der Rechnung aufgeführten Artikel aktualisiert.
Dieses Beispiel ist eine typische Situation für eine Transaktion. Sie müssen sicher sein, dass Sie all diese Datensätze während der Operation sichern bzw. die Transaktion abbrechen können, wenn sich ein Datensatz nicht hinzufügen oder aktualisieren lässt. Mit anderen Worten, Sie müssen verknüpfte Daten sichern.
Ohne Transaktion ist die logische Datenintegrität Ihrer Datenbank nicht gewährleistet. Ist zum Beispiel ein Datensatz in der Tabelle [Parts] gesperrt, kann die Anzahl im Datenfeld [Parts]In Warehouse nicht aktualisiert werden. Dieses Feld ist also logisch nicht mehr korrekt. Die Summe der verkauften Artikel und der Lagerbestand sind nicht identisch mit der im Datensatz eingegebenen Anzahl. Mit einer Transaktion verhindern Sie solch eine Situation.
Es gibt verschiedene Arten, bei der Dateneingabe mit Transaktionen zu arbeiten:
1. Sie können 4D die Verwaltung überlassen. Aktivieren Sie dazu in der Designumgebung im Dialogfenster Datenbankeigenschaften die Option Automatische Transaktionen bei Dateneingabe. In diesem Fall startet 4D die Transaktion und bestätigt oder löscht sie dann, je nachdem, ob Sie die Dateneingabe bestätigen oder annullieren. Geben Sie Daten in ein Formular ein mit einer verknüpften Tabelle in einem Unterformular, benötigen Sie eine Transaktion. Diese Option wird auf die gesamte Datenbank angewendet.
Wollen Sie die Transaktion selbst verwalten, setzen Sie die Befehle START TRANSACTION, VALIDATE TRANSACTION und CANCEL TRANSACTION ein.
2. Wir schreiben beispielsweise:
READ WRITE([Invoice Lines]) READ WRITE([Parts]) INPUT FORM([Invoices];"Input") Repeat START TRANSACTION ADD RECORD([Invoices]) If (OK=1) VALIDATE TRANSACTION Else CANCEL TRANSACTION End if Until (OK=0) READ ONLY(*)
3. Um das Datensatzsperren während der Dateneingabe zu reduzieren, können Sie auch Transaktionen von der Formularmethode aus steuern und auf die Tabellen nur wenn notwendig, im LESE/SCHREIBMODUS zugreifen.
Sie führen die Dateneingabe im Eingabeformular für [Invoices] aus, die die verknüpfte Tabelle [Invoice Lines] in einem Unterformular einhält. Das Formular hat zwei Schaltflächen: bCancel und bOK, beide führen keine Aktion aus.
Die Schleife zum Hinzufügen lautet:
READ WRITE([Invoice Lines]) READ ONLY([Parts]) INPUT FORM([Invoices];"Input") Repeat ADD RECORD([Invoices]) Until (bOK=0) READ ONLY([Invoice Lines])
Beachten Sie, dass die Tabelle [Parts] nun während der Dateneingabe im Modus Nur Lesen ist. Der Zugriff im Lese-/ Schreibmodus ist nur verfügbar, wenn die Dateneingabe bestätigt wird.
Die Transaktion wird in folgender [Invoices] Eingabeformularmethode gestartet:
Case of : (Form event=On Load) START TRANSACTION [Invoices]Invoice ID:=Sequence number([Invoices]Invoice ID) Else [Invoices]Total Invoice:=Sum([Invoice Lines]Total line) End case
Klicken Sie auf die Schaltfläche bCancel, muss sowohl die Dateneingabe als auch die Transaktion annulliert werden.
Die Objektmethode für die Schaltfläche bCancel lautet:
Case of : (Form event=On Clicked) CANCEL TRANSACTION CANCEL End case
Klicken Sie auf die Schaltfläche bValidate, muss die Dateneingabe angenommen und die Transaktion bestätigt werden. Die Objektmethode für die Schaltfläche bOK lautet:
Case of : (Form event=On Clicked) $NbLines:=Records in selection([Invoice Lines]) READ WRITE([Parts]) ` Wechsle in den Lese/Schreibzugriff für die Tabelle [Parts] FIRST RECORD([Invoice Lines]) ` Starte mit der ersten Zeile $ValidTrans:=True ` Nimm an, alles ist OK For ($Line;1;$NbLines) ` Für jede Zeile RELATE ONE([Invoice Lines]Part No) OK:=1 ` Nimm an, fortzufahren While (Locked([Parts]) & (OK=1)) ` Versuche, den Datensatz im Lese/Schreibzugriff zu erhalten CONFIRM("Der Artikel "+[Invoice Lines]Part No+" wird benutzt. Warten?") If (OK=1) DELAY PROCESS(Current process;60) LOAD RECORD([Parts]) End if End while If (OK=1) ` Aktualisiere Anzahl im Lager [Parts]In Warehouse:=[Parts]In Warehouse-[Invoice Lines]Quantity SAVE RECORD([Parts]) ` Sichere Datensatz Else $Line:=$NbLines+1 `Verlasse die Schleife $ValidTrans:=False End if NEXT RECORD([Invoice Lines]) ` Gehe in nächste Zeile End for READ ONLY([Parts]) ` Setze Tabelle in Status Nur Lesen If ($ValidTrans) SAVE RECORD([Invoices]) ` Sichere Datensatz in Rechnungen VALIDATE TRANSACTION ` Bestätige alle Änderungen in der Datenbank Else CANCEL TRANSACTION ` Brich Transaktion ab End if CANCEL ` Verlasse Formular End case
In diesem Code rufen wir den Befehl CANCEL unabhängig von der Schaltfläche auf. Der neue Datensatz wird nicht durch Aufrufen von ACCEPT bestätigt, sondern durch den Befehl SAVE RECORD. Beachten Sie, dass zusätzlich SAVE RECORD unmittelbar vor dem Befehl VALIDATE TRANSACTION aufgerufen wird. So ist das Sichern des [Invoices] Datensatzes aktueller Teil der Transaktion. Das Aufrufen des Befehls ACCEPT bestätigt auch den Datensatz, in diesem Fall würde die Transaktion ebenfalls den Datensatz bestätigen, die Transaktion würde jedoch vor Sichern des [Invoices] Datensatzes bestätigt. Demnach würde der Datensatz außerhalb der Transaktion bestätigt.
Bei der Dateneingabe können Sie die Transaktionen entweder von 4D verwalten lassen oder - wie in den obigen Beispielen gezeigt - in Ihrer Datenbank individuell einstellen. Das Steuern von gesperrten Datensätzen im letzten Beispiel kann noch weiter entwickelt werden.
Referenz
CANCEL TRANSACTION, In transaction, START TRANSACTION, VALIDATE TRANSACTION.