Séparation de la logique métier de la logique DB avec les transactions

11

architecture

Nous avons trois couches dans notre application. Couche de service pour fournir une API externe. Couche BO pour notre logique métier et une couche DAO pour notre connexion à la base de données.

Disons que chaque fois que nous mettons à jour un fichier, nous voulons également changer quelque chose dans le dossier, par exemple «date de dernière modification». Cela doit être fait dans une transaction. Soit il réussit et le fichier et le dossier sont modifiés. Ou il y a un échec et la transaction est annulée afin que les deux objets soient dans l'état précédent.

L'action "Modifier un dossier lorsqu'un fichier est modifié" est une logique purement commerciale. Cela signifierait donc qu'il appartient à la couche BO. Cependant, nous utilisons Objectify pour notre base de données, donc pour démarrer une transaction, nous devons appeler ofy (). Transact (...). Si nous appelons cette fonction dans la couche BO, cela brise notre conception car il y aura des appels spécifiques à la base de données (Objectify) dans notre couche Business.

Quelle serait une solution propre à ce problème?

Serge Hendrickx
la source
Impossible d' FileBOappeler en FolderBO.edit(newDate)raison du problème de transaction?
Repéré
java n'a-t-il pas un équivalent de TransactionScope c #?
Ewan
En Java, la portée de la transaction dépend du framework que vous utilisez. Dans JEE, il pourrait être géré par le serveur d'application, mais il est généralement défini et géré de manière déclarative via des cadres comme Spring (annotations via, xml, ...)
Laiv
Vous vous inquiétez moins d'essayer de rendre différentes "couches" de votre application fonctionnellement indépendantes / ignorantes les unes des autres. Embrassez l'idée que votre code est conçu pour l'architecture qu'il prend en charge et concentrez-vous plutôt sur la bonne composition de ce code par rapport à lui-même.
Ant P

Réponses:

5

La façon dont vous coupez vos transactions est en effet une logique commerciale. Laissez donc votre couche DAO fournir une API indépendante du framework db pour la transactméthode que vous avez mentionnée (et probablement pour des choses comme commitet rollback). Ensuite, vous pouvez l'utiliser à partir de votre couche BO sans le rendre dépendant de votre base de données ou de votre framework db.

Doc Brown
la source
4

On dirait qu'Objectify est conçu pour les transactions de type atomique ( Google Application Engine Transactions ). Il vous demandera de développer votre propre abstraction de la gestion des transactions .

Dans ce cas. l'abstraction continue Comment déléguer la gestion des transactions aux couches supérieures?

L'approche @DocBrown me semble la solution plus rapide et plus propre à implémenter dans l'architecture donnée ( architecture en couches ).

Parce que nous manquons trop d'informations sur l'application et son contexte, la solution de Doc me semble également la plus sûre.

Cependant, je suggère de jeter un œil au modèle de conception UnitOfWork pour la couche métier . Je pense que cela convient à la gestion des transactions proposée par Objectify .

En résumé, le modèle vise à encapsuler les règles métier dans les transactions commerciales (unités de travail). Le modèle permet l'héritage entre B.T et jusqu'à présent je vois, Objectify aussi. Il prend même en charge la composition. Donc, soit par composition, soit par héritage, l'approche permet des B.T complexes .

Appliqué à l'architecture donnée, ressemblerait à:

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