Autocommit und Before Commit Events – Keine Liebesgeschichte

Juni 12, 2020 4 Von Andreas

Ich bin gerade über etwas gestolpert was mir das Leben etwas schwer gemacht hat. Vielleicht hilft dieser Artikel anderen nicht in das gleiche Problem zu laufen. Aber fangen wir vorne an.

Ein nettes Before Commit Pattern

Ein Szenario was ich schon sehr oft gesehen habe ist folgendes:

Wenn sich ein bestimmtes Attribut eines Datensatzes verändert soll eine Aktion ausgelöst werden. Ein Beispiel hierfür wäre ein Objekt mit einem Status, welches bei jeder Statusänderung eine Benachrichtigung erzeugen soll.

Ein ziemlich praktisches Pattern hierfür ist es, in einem Before Commit Event, das zu committende Objekt in seinem alten Zustand aus der Datenbank zu retrieven und mit dem aktuellen zu vergleichen. Sollten Änderungen festgestellt werden wird die Benachrichtigung erzeugt.

Das ganze würde folgendermaßen aussehen:

Das ganze funktioniert hervorragend, sofern dieses Before Commit Event läuft bevor das Objekt in der Datenbank geupdatet ist. Und hier kann uns nun leider das Autocommit in die Quere kommen.

Das Mendix Autocommit „Feature“

Mendix ist bestrebt dem LowCode Entwickler dabei zu helfen seine Daten möglichst konsistent zu halten. Hierzu gibt es unter Anderem ein Feature namens Autocommit.

Wird auf einem Objekt eine Assoziation zu einem anderen Objekt gesetzt und dieses andere Objekt existiert zu diesem Zeitpunkt noch nicht in der Datenbank, so wird dieses nicht existierende Objekt automatisch auch committed (autocommitted). Somit muss sich der Entwickler nicht sorgen eine Assoziation gesetzt zu haben die so später gar nicht in der Datenbank existiert.

Wird in diesem Beispiel ein Objekt vom Typ OtherEntity committed welches auf ein nicht committetes Objekt vom Typ Entity verweist, so wird letzteres autocommitted.

Das Problem

Hierbei entsteht möglicherweise ein Problem. Mendix triggert bei einem Autocommit keine Events. Es schreibt die Daten einfach in die Datenbank. Dies ist insofern sinnvoll, als dass der Entwickler ja kein Commit angestoßen hat. Es birgt jedoch gefahren wenn z.B. ein Before Commit Event darauf angewiesen ist VOR dem Commit zu laufen (Wie das oben beschriebene Pattern). Wird nämlich das zuvor autocommittete Objekt nochmals explizit committed, so befindet es sich bereits in der Datenbank. Der Vergleich zwischen dem alten und dem neuen Status führt also zu keinem brauchbaren Ergebnis mehr.

Vorsicht bei der Commit Reihenfolge

In diesem Beispiel findet durch das Commit von OtherEntity ein Autocommit von Entity statt. Das Before Commit Event auf Entity wird erst getriggert, wenn Entity im Microflow committet wird. Zu diesem zeitpunkt stehen die Änderungen schon in der Datenbank. Das notification Pattern wird in jedem Fall fehlschlagen.

In diesem Fall wird zuerst der Commit auf Entity ausgeführt. Das notification Pattern funktioniert wie erwartet. Es findet kein Autocommit statt.

Fazit

Ich nehme zwei Erkenntnisse für mich mit.

  1. Die Reihenfolge in der Objekte committed werden ist wichtig. Unterschiedliche Reihenfolgen können zu unterschiedlichen Ergebnissen führen. Ideal ist es hier wenn man versucht durch die Reihenfolge ein Autocommit zu verhindern.
  2. Da erstens nicht immer möglich ist (Es könnten z.B. 3 oder Mehr Objekte so aufeinander verweisen, dass ein Autocommit nicht verhindert werden kann), sollte man sehr genau darauf achten wo man Patterns wie das oben beschriebene verwendet. Möchte man wirklich sicher gehen, dass bestimmte Aktionen auf einem wohldefinierten Datenstand ausgeführt werden, kann es besser sein, diese Aktionen nicht in einem Before Commit Event sondern im Microflow auszuführen in dem das Objekt committed wird. Idealerweise bevor ein Autocommit stattfinden kann.