Warum mit der @Transactional mit @Service statt mit @Controller
Habe ich gesehen, dass viele Kommentare in stack-überlauf Artikel fand ich bestimmte Dinge entweder @Transactional Verwendung mit @Service oder mit @Controller
"In der Regel sollte eine Transaktion an den service layer".
"Der normale Fall wäre, zu kommentieren, die auf einem service-layer-Ebene"
"Denken Transaktionen gehören auf den Service-layer. Es ist derjenige, der weiß, dass über die Einheiten von Arbeit und use-cases. Es ist die richtige Antwort, wenn Sie mehrere DAOs injiziert in einen Dienst, arbeiten zusammen in einer einzigen Transaktion." [Quelle]
Nachteil mit @transactional mit @service layer
Hätte ich 2 Methoden zum Beispiel saveUser() und saveEmail() (weil ich die speichern die E-Mails in einer Datenbank, um Sie später zu senden - wie eine Warteschlange) ich würde in meinem Dienst eine Methode saveUserAndSendEmail(Benutzer Benutzer), die transaktional sein. [Quelle]
Es bedeutet, dass ich viele Methoden in der service-Schicht statt einer Speichern Generische Methode, die als Folge von
public <T> long save(T entity) throws DataAccessException {
Session session = sessionFactory.getCurrentSession();
long getGenVal=(Long) session.save(entity);
return getGenVal;
}
Entsprechend der oben genannten Lösung , das heißt, wir haben viele Methoden, die wie folgt LOL..
public <T> long saveAccount(T entity)....
public <T> long saveWithAuditLog(T entity, K entity1)....
public <T> long saveWithAuditLogAndEntries(T entity, K entity, M entity)....
ÜBERWINDUNG dieser situation
Ich DIE @Transactional-in @Controller und Nur eine Generische Methode Speichern und speichern Sie alle Personen/Modell mit dieser einfachen Methode speichern. und wenn eine Methode scheitern zu speichern, dann werden alle Transaktionen im controller rollback erfolgreich.
Andere situation, die gewährleisten, dass die @Transactional sollte die Verwendung mit @Controller
In @Controller:
pt.save(entity1);
pt.save(entity2);
int a = 2/0;
pt.save(entity3);
Im Falle , @Transactional über den Dienst, die ersten 2 Person erfolgreich gerettet, aber den Dritten nicht es nicht rollback alle die Transaktion
Im Falle , @Transactional auf @Controller alle rollback der Transaktion als Ausnahme auftreten
warum stack-überlauf fragte , "Don' T do Transaktionen in Ihrem controller. Setzen Sie Sie in Ihrem Dienst Schicht-Klassen."?
[Quelle]
- Bitte nicht verwenden Sie den code-markup für text. Sie können block-Zitate für Zitate, wenn Sie wollen.
- Ich denke, die beste Lösung in dem Fall ist, erstellen Sie eine weitere Ebene zwischen den
controller
und dieservice
. Wie ich es sehe diecontroller
nur verarbeitet Anrufe und bereiten vars zu verarbeiten und wirken Logik auf Sie. Dieservice
behandeln alle DB Sachen. und das Modell sollte zwischen dencontroller
und dieservice
tun können, eine gewisse Logik. In deinem Beispiel tun einige Aktionen spart eine Logik ist, die Aktionen auf den Daten . welche Mittel setzen Sie Sie inmodel
und warpmodel
mittransactional
wenn nötig - Ihre
saveUser()
undsaveEmail()
Methoden sollten in der DAO-Schicht. Dann machen Sie SiesaveUserAndSendEmail(User user)
Methode in der Service-Ebene Transaktions.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Du fragst nach best-practice-und best practice zu markieren
@Transactional
in der service-Ebene, weil ein@Controller
sollte nicht bewusst sein, Daten-Persistenz in einer MVC-Logik.@Service
ist aufgebaut auf den use-case erzeugt, von der Analyse und kennt Einheit und arbeitet, ist auch klar denken in Bezug auf die Wiederverwendung: wenn Sie wechseln von einem web-Kontext auf einem desktop ein (zum Beispiel, oder einige andere visuelle frontend), wo@Controller
Schicht nicht vorhanden ist, Sie keine Probleme haben, da alles gekapselt in der service-Ebene.Ein
@Service
ist ein Vertrag und eine änderung in der Darstellungsschicht sollte nicht verlangen, ein umschreiben des@Service
code.Aber der Frühling kümmern sich nicht darum, wo Sie Ihre Ihre Transaktion Grenzen, kann man auf
@Controller
aber Ihre Anwendung wird schwieriger zu erhalten sein.Ich hoffe das ist klar genug. Sorry wenn nicht, Englisch ist nicht meine Muttersprache.
nur, damit andere wissen, Schnittstelle Anmerkungen sind entmutigt
Frühling empfiehlt, dass Sie nur kommentieren konkreten Klassen (und Methoden von konkreten Klassen) mit der @Transactional annotation, im Gegensatz zu Anmerkungen zu Schnittstellen. Man kann sicherlich legen Sie die @Transactional-annotation ein interface (oder eine interface-Methode), dies funktioniert aber nur, wie Sie es erwarten würden, wenn Sie mit Hilfe von interface-basierten proxies. Die Tatsache, dass Java-Annotationen nicht vererbt werden von Schnittstellen bedeutet, dass, wenn Sie Klasse-basierte proxies ( proxy-target-class="true") oder die Weberei-basierenden Aspekt ("mode="aspectj"), dann wird die Transaktion-Einstellungen werden nicht erkannt, durch das proxying-und Web-Infrastruktur, und das Objekt wird nicht gewickelt, in einer Transaktions-proxy, das wäre ausgesprochen schlecht.
Controller ist fest in der view-Schicht, die können jederzeit geändert werden. Der service besitzt immer noch Einheiten der Arbeit und sollten korrekt arbeiten, unabhängig davon, welche Ansicht zugreift. Meine Antwort hier noch steht.
saveAccount
saveAccountAudit
saveAccountAuditEntries
?Erstellte ich eine der oberen Schicht Dienste, die andere (nicht-Transaktions -) Dienstleistungen. Und die Obere-Schicht-Dienst ist transactional.