Die Frage aus dem Titel im Code:
@Transactional (readonly = true)
public interface FooService {
void doSmth ();
}
public class FooServiceImpl implements FooService {
...
}
vs.
public interface FooService {
void doSmth ();
}
@Transactional (readonly = true)
public class FooServiceImpl implements FooService {
...
}
quelle
JdkDynamicAopProxy
bei jedem Methodenaufruf (siehe auchDefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice()
) alle Bean-Advisors durchlaufen werden , was im Falle einer deklarativen Transaktionskonfiguration der Fall istBeanFactoryTransactionAttributeSourceAdvisor
. Im GegenzugTransactionAttributeSourcePointcut#matches()
wird aufgerufen, der die transaktionsbezogenen Informationen sammeln soll. Es wird die Zielklasse übergeben und kann immer alle Schnittstellen durchlaufen, die diese Klasse implementiert. Nun: Warum kann das nicht zuverlässig funktionieren?@Transactional
Anmerkungen gelten würde? Also, obwohl alles möglich ist , beschuldige ich Spring nicht. jira.springsource.org/browse/SPR-975Sie können sie in die Benutzeroberfläche einfügen, aber seien Sie gewarnt, dass in einigen Fällen möglicherweise keine Transaktionen stattfinden. Siehe den zweiten Tipp in Abschnitt 10.5.6 der Spring-Dokumente:
Ich würde empfehlen, sie aus diesem Grund in die Implementierung aufzunehmen.
Außerdem scheinen mir Transaktionen ein Implementierungsdetail zu sein, sodass sie in der Implementierungsklasse sein sollten. Stellen Sie sich Wrapper-Implementierungen für die Protokollierung oder Testimplementierungen (Mocks) vor, die nicht transaktional sein müssen.
quelle
Die Empfehlung von Spring lautet, dass Sie die konkreten Implementierungen anstelle einer Schnittstelle mit Anmerkungen versehen. Es ist nicht falsch, die Annotation auf einer Schnittstelle zu verwenden. Es ist nur möglich, diese Funktion zu missbrauchen und versehentlich Ihre @ Transaction-Deklaration zu umgehen.
Wenn Sie etwas Transaktionales in einer Schnittstelle markiert haben und dann im Frühjahr auf eine der implementierenden Klassen an anderer Stelle verweisen, ist es nicht ganz offensichtlich, dass das von Spring erstellte Objekt die Annotation @Transactional nicht berücksichtigt.
In der Praxis sieht es ungefähr so aus:
quelle
Unterstützung von @Transactional für die konkreten Klassen:
Ich ziehe es vor, eine Lösung in drei Abschnitten zu entwerfen: eine API, eine Implementierung und ein Web (falls erforderlich). Ich versuche mein Bestes, um die API so leicht / einfach / POJO wie möglich zu halten, indem ich Abhängigkeiten minimiere. Es ist besonders wichtig, wenn Sie es in einer verteilten / integrierten Umgebung spielen, in der Sie die APIs häufig gemeinsam nutzen müssen.
Für das Einfügen von @Transactional sind Spring-Bibliotheken im API-Bereich erforderlich, was meiner Meinung nach nicht effektiv ist. Daher ziehe ich es vor, es in der Implementierung hinzuzufügen, in der die Transaktion ausgeführt wird.
quelle
Das Einfügen in die Benutzeroberfläche ist in Ordnung, solange sich alle vorhersehbaren Implementierer Ihrer IFC um TX-Daten kümmern (Transaktionen sind keine Probleme, mit denen sich nur Datenbanken befassen). Wenn sich die Methode nicht um TX kümmert (aber Sie müssen sie für den Ruhezustand oder was auch immer dort ablegen), setzen Sie sie auf das Gerät.
Außerdem ist es möglicherweise etwas besser,
@Transactional
die Methoden in der Benutzeroberfläche zu platzieren:quelle