Wednesday, May 26, 2010

ForUpdate-Datensatz nach dem Einfügen eines Datensatzes

Jedes mal, wenn ein Datensatz mit der insert()- oder der doInsert()-Methode auf der Datenbank erzeugt wird, erhält man den neu erzeugten Datensatz mit dem Prädikat forupdate. Das heisst im Prinzip, dass ich den Datensatz beliebig mit update() oder doUpdate() ändern kann ohne ich vorher von der Datenbank neu lesen zu müssen.

Allerdings gibt es oft Probleme, wenn das ganze nicht in einer Datenbanktransaktion gehalten wird: U.u. wird der Datensatz nämlich in der Zwischenzeit verändert und das führt zu einer Ausnahme sobald update() oder doUpdate() die Änderung in die Datenbank schreiben soll:

Ein Datensatz in Debitoren (Tabellenname) kann nicht bearbeitet werden.
Aktualisierungskonflikt, weil ein anderer Benutzerprozess den Datensatz gelöscht oder mindestens ein Feld im Datensatz geändert hat.

Deshalb sollte man solchen Code vermeiden:

Table table;
;
table.KeyField = 'a';
table.insert();

table.AdditionalField = 'halli galli';
table.update();

Stattdessen sollte man ihn entweder so schreiben:

Table table;
;
ttsbegin;
table.KeyField = 'a';
table.insert();

table.AdditionalField = 'halli galli';
table.update();
ttscommit;

Oder so:

Table table;
;
table.KeyField = 'a';
table.insert();

// time consuming other code here

ttsbegin;
table.selectForUpdate(true);
table.reread();
table.AdditionalField = 'halli galli';
table.update();
ttscommit;

Je nach Anforderung ob der Datensatz in der Zwischenzeit verändert werden darf braucht es eine alles umfassende Datenbanktransaktion oder eben nicht.

No comments:

Post a Comment