Transaktionen mit Spring und JPA

1. Übersicht

In diesem Lernprogramm wird erläutert , wie Sie Spring Transactions richtig konfigurieren , wie Sie die Annotation @Transactional verwenden und welche allgemeinen Fallstricke auftreten.

Weitere Informationen zur Konfiguration der Kernpersistenz finden Sie im Tutorial Spring with JPA.

Grundsätzlich gibt es zwei verschiedene Möglichkeiten, Transaktionen zu konfigurieren - Anmerkungen und AOP -, die jeweils ihre eigenen Vorteile haben. Wir werden hier die häufigere Annotation-Konfiguration diskutieren.

2. Konfigurieren Sie Transaktionen

In Spring 3.1 wird die Annotation @EnableTransactionManagement eingeführt, die wir in einer @ Configuration- Klasse verwenden und die Transaktionsunterstützung aktivieren können:

@Configuration @EnableTransactionManagement public class PersistenceJPAConfig{ @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){ //... } @Bean public PlatformTransactionManager transactionManager(){ JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory( entityManagerFactoryBean().getObject() ); return transactionManager; } }

Doch wenn wir ein Frühling Boot - Projekt verwenden, und haben eine feder Daten- * oder Feder-tx Abhängigkeiten auf dem Classpath, dann Transaktionsverwaltung wird standardmäßig aktiviert .

3. Konfigurieren Sie Transaktionen mit XML

Vor 3.1 oder wenn Java keine Option ist, finden Sie hier die XML-Konfiguration mit annotationsgesteuerter Unterstützung und Namespace-Unterstützung:

4. Die @ Transactional Annotation

Mit konfigurierten Transaktionen können wir jetzt eine Bean mit @Transactional entweder auf Klassen- oder auf Methodenebene mit Anmerkungen versehen :

@Service @Transactional public class FooService { //... }

Die Anmerkung unterstützt auch die weitere Konfiguration :

  • der Propagationstyp der Transaktion
  • die Isolationsstufe der Transaktion
  • a Zeitüberschreitung für die von der Transaktion umschlossene Operation
  • ein readOnly-Flag - ein Hinweis für den Persistenzanbieter, dass die Transaktion schreibgeschützt sein sollte
  • die Rollback- Regeln für die Transaktion

Beachten Sie, dass das Rollback standardmäßig nur zur Laufzeit ausgeführt wird, nicht aktivierte Ausnahmen. Die aktivierte Ausnahme löst kein Rollback der Transaktion aus. Wir können dieses Verhalten natürlich mit den Annotationsparametern rollbackFor und noRollbackFor konfigurieren .

5. Mögliche Fallstricke

5.1. Transaktionen und Proxies

Auf hoher Ebene erstellt Spring Proxys für alle mit @Transactional kommentierten Klassen - entweder für die Klasse oder für eine der Methoden. Der Proxy ermöglicht es dem Framework, Transaktionslogik vor und nach der laufenden Methode einzufügen - hauptsächlich zum Starten und Festschreiben der Transaktion.

Es ist wichtig zu beachten, dass der Proxy standardmäßig ein Java Dynamic Proxy ist, wenn die Transaktions-Bean eine Schnittstelle implementiert. Dies bedeutet, dass nur externe Methodenaufrufe abgefangen werden, die über den Proxy eingehen. Selbstaufrufaufrufe starten keine Transaktion, selbst wenn die Methode die Annotation @Transactional enthält .

Eine weitere Einschränkung bei der Verwendung von Proxys besteht darin, dass nur öffentliche Methoden mit @Transactional kommentiert werden sollten. Bei Methoden mit anderen Sichtbarkeiten wird die Anmerkung einfach stillschweigend ignoriert, da diese nicht als Proxy verwendet werden.

In diesem Artikel werden weitere Fallstricke für das Proxying hier ausführlich beschrieben.

5.2. Ändern der Isolationsstufe

Wir können auch die Transaktionsisolationsstufe ändern:

@Transactional(isolation = Isolation.SERIALIZABLE)

Beachten Sie, dass dies tatsächlich in Frühjahr 4.1 eingeführt wurde. Wenn wir das obige Beispiel vor Spring 4.1 ausführen, führt dies zu:

org.springframework.transaction.InvalidIsolationLevelException : Standard-JPA unterstützt keine benutzerdefinierten Isolationsstufen - verwenden Sie einen speziellen JpaDialect für Ihre JPA-Implementierung

5.3. Schreibgeschützte Transaktionen

Das readOnly- Flag sorgt normalerweise für Verwirrung, insbesondere bei der Arbeit mit JPA. aus dem Javadoc:

Dies dient nur als Hinweis für das eigentliche Transaktionssubsystem. Dies führt nicht unbedingt zum Fehlschlagen von Schreibzugriffsversuchen. Ein Transaktionsmanager, der den schreibgeschützten Hinweis nicht interpretieren kann, löst keine Ausnahme aus, wenn er nach einer schreibgeschützten Transaktion gefragt wird.

Tatsache ist, dass wir nicht sicher sein können, dass eine Einfügung oder Aktualisierung nicht erfolgt, wenn das readOnly- Flag gesetzt ist. Dieses Verhalten ist herstellerabhängig, während JPA herstellerunabhängig ist.

Es ist auch wichtig zu verstehen, dass das readOnly- Flag nur innerhalb einer Transaktion relevant ist. Wenn eine Operation außerhalb eines Transaktionskontexts ausgeführt wird, wird das Flag einfach ignoriert. Ein einfaches Beispiel hierfür würde eine Methode aufrufen, die mit folgenden Anmerkungen versehen ist:

@Transactional( propagation = Propagation.SUPPORTS,readOnly = true )

aus einem nicht-transaktionalen Kontext - Eine Transaktion wird nicht erstellt und das readOnly- Flag wird ignoriert.

5.4. Transaktionsprotokollierung

Eine hilfreiche Methode zum Verständnis transaktionsbezogener Probleme ist die Feinabstimmung der Protokollierung in den Transaktionspaketen. Das relevante Paket in Spring ist " org.springframework.transaction", das mit einer Protokollierungsstufe von TRACE konfiguriert werden sollte.

6. Fazit

Wir haben die grundlegende Konfiguration der Transaktionssemantik unter Verwendung von Java und XML, die Verwendung von @Transactional und Best Practices einer Transaktionsstrategie behandelt.

Wie immer ist der in diesem Artikel vorgestellte Code auf Github verfügbar.