Trennung von Geschäftslogik und DB-Logik durch Transaktionen

11

die Architektur

Wir haben drei Schichten in unserer Anwendung. Service-Schicht zur Bereitstellung einer externen API. BO-Schicht für unsere Geschäftslogik und DAO-Schicht für unsere Datenbankverbindung.

Angenommen, wir möchten jedes Mal, wenn wir eine Datei aktualisieren, auch etwas im Ordner ändern, z. B. das Datum der letzten Änderung. Dies muss in einer Transaktion erfolgen. Entweder ist es erfolgreich und sowohl Datei als auch Ordner werden bearbeitet. Oder es liegt ein Fehler vor und die Transaktion wird zurückgesetzt, sodass sich beide Objekte im vorherigen Status befinden.

Die Aktion "Ordner bearbeiten, wenn eine Datei bearbeitet wird" ist reine Geschäftslogik. Das würde also bedeuten, dass es in die BO-Schicht gehört. Wir verwenden jedoch Objectify für unsere Datenbank. Um eine Transaktion zu starten, müssen wir ofy (). Transact (...) aufrufen. Wenn wir diese Funktion in der BO-Schicht aufrufen, bricht dies unser Design, da es in unserer Business-Schicht datenbankspezifische Aufrufe (Objectify) gibt.

Was wäre eine saubere Lösung für dieses Problem?

Serge Hendrickx
quelle
Sie können wegen des Transaktionsproblems nicht FileBOanrufen FolderBO.edit(newDate)?
Spotted
Hat Java kein Äquivalent zu c # TransactionScope?
Ewan
In Java hängt der Transaktionsbereich vom verwendeten Framework ab. In JEE könnte es vom App-Server verwaltet werden, wird aber normalerweise deklarativ über Frameworks wie Spring (über Anmerkungen, XML, ...) definiert und verwaltet
Laiv
Sorgen Sie sich weniger darum, verschiedene "Ebenen" Ihrer Anwendung funktionsunabhängig / unwissend voneinander zu machen. Nehmen Sie die Idee an, dass Ihr Code für die von ihm unterstützte Architektur erstellt wurde, und konzentrieren Sie sich stattdessen darauf, diesen Code in Bezug auf sich selbst gut zusammenzusetzen.
Ameise P

Antworten:

5

Wie Sie Ihre Transaktionen kürzen, ist in der Tat Geschäftslogik. Lassen Sie also Ihre DAO-Schicht eine db-Framework-unabhängige API für die von transactIhnen erwähnte Methode (und wahrscheinlich für Dinge wie commitund rollback) bereitstellen . Dann können Sie es von Ihrer BO-Ebene aus verwenden, ohne es von Ihrer Datenbank oder Ihrem Datenbank-Framework abhängig zu machen.

Doc Brown
quelle
4

Es sieht so aus, als ob Objectify für atomähnliche Transaktionen ( Google Application Engine-Transaktionen ) entwickelt wurde. Sie müssen eine eigene Abstraktion des Transaktionsmanagements entwickeln .

In diesem Fall. Die Abstraktion geht weiter. Wie delegiere ich das Transaktionsmanagement an die oberen Ebenen?

Der @ DocBrown-Ansatz sieht für mich die schnellere und sauberere Lösung für die Implementierung in die angegebene Architektur ( Layered Architecture ).

Da wir zu viele Informationen über die Anwendung und ihren Kontext vermissen, scheint mir die Lösung von Doc auch die sicherste zu sein.

Ich würde jedoch empfehlen, einen Blick auf das UnitOfWork- Entwurfsmuster für die Business-Ebene zu werfen . Ich denke, es passt zum Transaktionsmanagement von Objectify .

Kurz zusammengefasst zielt das Muster darauf ab, Geschäftsregeln in Geschäftstransaktionen (Arbeitseinheiten) zu kapseln . Das Muster erlaubt die Vererbung zwischen B.Ts und soweit ich sehe, auch Objectify . Es unterstützt sogar die Komposition. Also entweder durch die Zusammensetzung oder Vererbung ermöglicht es der Ansatz komplexen B.Ts .

Auf die gegebene Architektur angewendet, würde aussehen wie:

FileService -> FileBO : new EditFileTransaction().execute()
                           |-> ofy().transact(...)
                           |--> FileDAO.actionA()
                           |--> FolderDAO.actionA()
                           |-> [ofy().commit(...)|ofy().rollback()]
Laiv
quelle