Transaktionen mit Spring und JPA

Transaktionen mit Spring und JPA

1. Überblick

In diesem Tutorial werdenthe right way to configure Spring Transactions, die Verwendung der Annotation@Transactional und allgemeine Fallstricke erläutert.

Weitere Informationen zur Konfiguration der Kernpersistenz finden Sie inSpring with JPA tutorial.

Grundsätzlich gibt es zwei verschiedene Möglichkeiten, um Transaktionen zu konfigurieren: Anmerkungen und AOP - jede mit ihren eigenen Vorteilen. Wir werden hier die häufigere Annotation-Konfiguration diskutieren.

Weitere Lektüre:

Separate Spring DataSource für Tests konfigurieren

Ein schnelles, praktisches Tutorial zum Konfigurieren einer separaten Datenquelle zum Testen in einer Spring-Anwendung.

Read more

Kurzanleitung zum Laden von Anfangsdaten mit Spring Boot

Ein schnelles und praktisches Beispiel für die Verwendung von data.sql- und schema.sql-Dateien in Spring Boot.

Read more

Ruhezustand / JPA-SQL-Anweisungen von Spring Boot anzeigen

Erfahren Sie, wie Sie die Protokollierung der generierten SQL-Anweisungen in Ihrer Spring Boot-Anwendung konfigurieren können.

Read more

2. Konfigurieren Sie Transaktionen ohne XML

In Spring 3.1 werdenthe @EnableTransactionManagement annotation 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;
   }
}

Wenn wir jedoch ein Spring Boot-Projekt verwenden und Spring-Data- * oder Spring-TX-Abhängigkeiten vom Klassenpfad haben, ist die Transaktionsverwaltung standardmäßig aktiviert.

3. Konfigurieren Sie Transaktionen mit XML

Vor 3.1 oder wenn Java keine Option ist, finden Sie hier die XML-Konfiguration unter Verwendung vonannotation-driven und der Namespace-Unterstützung:


   

4. Die Annotation@Transactional

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

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

Die Annotation unterstützt auchfurther configuration:

  • diePropagation Type der Transaktion

  • dieIsolation Level der Transaktion

  • aTimeout für die von der Transaktion umschlossene Operation

  • areadOnly flag - ein Hinweis für den Persistenzanbieter, dass die Transaktion schreibgeschützt sein sollte

  • dieRollback Regeln für die Transaktion

Beachten Sie, dass das Rollback standardmäßig nur zur Laufzeit ausgeführt wird (nicht aktivierte Ausnahmen). The checked exception does not trigger a rollback der Transaktion. Wir können dieses Verhalten natürlich mit den AnnotationsparameternrollbackFor undnoRollbackFor konfigurieren.

5. Möglichen Gefahren

5.1. Transaktionen und Proxies

Auf einem hohen NiveauSpring creates proxies for all the classes annotated with @Transactional - entweder für die Klasse oder für eine der Methoden. Der Proxy ermöglicht es dem Framework, Transaktionslogik vor und nach der ausgeführten 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. Any self-invocation calls will not start any transaction,, auch wenn die Methode die Annotation@Transactional enthält.

Eine weitere Einschränkung bei der Verwendung von Proxys besteht darin, dassonly public methods should be annotated with @Transactional. Methoden für andere Sichtbarkeiten die Anmerkung einfach stillschweigend ignorieren, da diese nicht als Proxys verwendet werden.

5.2. Ändern der Isolationsstufe

Wir können auch die Transaktionsisolationsstufe ändern:

@Transactional(isolation = Isolation.SERIALIZABLE)

Beachten Sie, dass dies in Frühjahr 4.1 tatsächlichintroduced war. 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 für Ihre JPA-Implementierung ein speziellesJpaDialect

5.3. Schreibgeschützte Transaktionen

Das FlagreadOnly erzeugt normalerweise Verwirrung, insbesondere bei der Arbeit mit JPA. aus dem Javadoc:

Dies dient nur als Hinweis für das eigentliche Transaktionssubsystem. not necessarily führt zu fehlgeschlagenen Schreibzugriffsversuchen. Ein Transaktionsmanager, der den schreibgeschützten Hinweis nicht interpretieren kann, löstnot eine Ausnahme aus, wenn er nach einer schreibgeschützten Transaktion gefragt wird.

Tatsache ist, dasswe can’t be sure that an insert or update will not occur when the readOnly flag is set. Dieses Verhalten ist herstellerabhängig, während JPA herstellerunabhängig ist.

Es ist auch wichtig zu verstehen, dassthe readOnly flag is only relevant inside a transaction. Wenn eine Operation außerhalb eines Transaktionskontexts ausgeführt wird, wird das Flag einfach ignoriert. Ein einfaches Beispiel hierfür würde eine mit folgenden Anmerkungen versehene Methode aufrufen:

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

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

5.4. Transaktionsprotokollierung

Eine hilfreiche Methode, um transaktionsbezogene Probleme zu verstehen, ist die Feinabstimmung der Protokollierung in den Transaktionspaketen. Das relevante Paket im Frühjahr lautet „org.springframework.transaction”, which should be configured with a logging level of TRACE.

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 Codeover on Github verfügbar.