Warum @Transactional mit @Service anstelle von @Controller verwenden

8

Ich habe viele Kommentare in Stack-Overflow-Artikeln gesehen. Ich habe bestimmte Dinge über @Transactional mit @Service oder @Controller herausgefunden

  

"Normalerweise sollte man eine Transaktion auf der Serviceebene platzieren."

     

"Der normale Fall wäre, Anmerkungen auf Service-Ebene zu machen"

     

"Think-Transaktionen gehören zur Service-Schicht. Sie kennen Arbeitseinheiten und Anwendungsfälle. Sie sind die richtige Antwort, wenn mehrere DAOs in einen Service integriert werden, die in einer einzigen Transaktion zusammenarbeiten müssen." [Quelle]

Nachteil, um @transactional mit der @service-Ebene zu verwenden

  

Wenn ich zwei Methoden hätte, zum Beispiel saveUser () und saveEmail () (weil ich die E-Mails in einer Datenbank speichern würde, um sie später zu senden - wie eine Warteschlange), würde ich in meinem Dienst eine Methode saveUserAndSendEmail (User user) erstellen sei transaktional. [Quelle]

Es bedeutet, dass ich viele Methoden in der Serviceebene anstelle einer generischen Methode wie folgt erstellen

%Vor%

Gemäß der obigen Lösung bedeutet dies, dass wir viele Methoden haben, wie LOL zu folgen.

public <T> long saveAccount(T entity)....

public <T> long saveWithAuditLog(T entity, K entity1)....

public <T> long saveWithAuditLogAndEntries(T entity, K entity, M entity)....

Diese Situation ÜBERLEBEN

ICH VERWENDE @Transactional in @Controller und mache einfach eine generische Speichermethode und speichere alle Objekte / Modelle mit dieser einfachen Speichermethode. und wenn eine Methode nicht speichern kann, werden alle Transaktionen im Controller erfolgreich zurückgesetzt.

Andere Situation, die sicherstellt, dass @Transactional mit @Controller verwendet werden sollte

In @Controller:

%Vor%

Für den Fall, dass @Transactional on Service die erste 2 Entität erfolgreich gespeichert hat, aber nicht die gesamte Transaktion rückgängig gemacht hat

Im Falle von @Transactional auf @Controller tritt das gesamte Zurücksetzen der Transaktion als Ausnahme auf

Warum der Stack-Überlauf gefragt hat: "Machen Sie keine Transaktionen in Ihrem Controller. Fügen Sie sie in Ihre Service-Layer-Klassen ein." [source]

    
Shahid Ghafoor 28.08.2013, 21:01
quelle

4 Antworten

15

Sie fragen nach Best Practice, und die beste Vorgehensweise besteht darin, @Transactional in der Service-Schicht zu markieren, weil eine @Controller die Datenpersistenz in einer MVC-Logik nicht kennen sollte.
@Service wird bei Verwendung erstellt -Erzeugt aus der Analyse und weiß über die Einheit der Werke und ist auch im Sinne der Wiederverwendung realisiert: wenn Sie von einem Web-Kontext auf einen Desktop-Kontext (zum Beispiel oder ein anderes visuelles Frontend) wechseln, wo @Controller layer nicht existieren Sie haben keine Probleme, weil alles in Service-Layer eingekapselt ist.
A @Service ist ein Vertrag und eine Änderung in der Präsentationsschicht sollte kein Neuschreiben von @Service code erfordern.
Aber Spring kümmert sich nicht darum, wo Sie Ihre Transaktionsgrenzen setzen, Sie können @Controller anlegen, aber Ihre Anwendung wird möglicherweise schwieriger zu pflegen sein.

Ich hoffe, das ist klar genug. Entschuldigung wenn nicht; Englisch ist nicht meine Muttersprache.

    
Luca Basso Ricci 28.08.2013 21:51
quelle
2

nur so andere wissen, Schnittstelle Anmerkungen werden abgeraten

Spring empfiehlt, dass Sie nur konkrete Klassen (und Methoden von konkreten Klassen) mit der Annotation @Transactional anstelle von Annotationsschnittstellen annotieren. Sie können die Annotation @Transactional auf eine Schnittstelle (oder eine Interface-Methode) setzen, aber das funktioniert nur so, wie Sie es erwarten würden, wenn Sie Interface-basierte Proxies verwenden. Die Tatsache, dass Java-Annotationen nicht von Interfaces vererbt werden, bedeutet, dass wenn Sie klassenbasierte Proxies (proxy-target-class="true") oder den webbasierten Aspekt (mode="aspectj") verwenden, die Transaktionseinstellungen sind von der Proxy- und Web-Infrastruktur nicht erkannt, und das Objekt wird nicht in einen Transaktions-Proxy eingebunden, was ausgesprochen schlecht wäre.

    
user3719889 10.02.2016 03:04
quelle
1

Ich habe einen Dienst der oberen Schicht erstellt, der andere (nichttransaktionale) Dienste verwendet. Und der Service der oberen Schicht ist transaktional.

%Vor%     
Yan Khonski 20.11.2015 14:34
quelle
0

Der Controller befindet sich fest in der Ansichtsebene, die jederzeit geändert werden kann. Der Dienst besitzt immer noch Arbeitseinheiten und sollte unabhängig davon, auf welche Ansicht zugegriffen wird, ordnungsgemäß funktionieren. Meine Antwort hier steht immer noch.

    
duffymo 28.08.2013 23:36
quelle