Transactions avec Spring et JPA

Transactions avec Spring et JPA

1. Vue d'ensemble

Ce didacticiel aborderathe right way to configure Spring Transactions, comment utiliser l'annotation@Transactional et les pièges courants.

Pour une discussion plus approfondie sur la configuration de la persistance principale, consultez lesSpring with JPA tutorial.

Fondamentalement, il existe deux manières différentes de configurer des transactions - les annotations et les AOP - chacune avec ses propres avantages. Nous allons discuter de la configuration d'annotation la plus courante ici.

Lectures complémentaires:

Configuration de sources de données de ressort distinctes pour les tests

Tutoriel rapide et pratique sur la configuration d'une source de données distincte à tester dans une application Spring.

Read more

Guide rapide sur le chargement de données initiales avec Spring Boot

Exemple rapide et pratique d'utilisation des fichiers data.sql et schema.sql dans Spring Boot.

Read more

Afficher les instructions SQL Hibernate / JPA à partir du démarrage printanier

Découvrez comment configurer la consignation des instructions SQL générées dans votre application Spring Boot.

Read more

2. Configurer les transactions sans XML

Spring 3.1 introduitthe @EnableTransactionManagement annotation que nous pouvons utiliser dans une classe@Configuration et activer le support transactionnel:

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{

   @Bean
   public LocalContainerEntityManagerFactoryBean
     entityManagerFactoryBean(){
      //...
   }

   @Bean
   public PlatformTransactionManager transactionManager(){
      JpaTransactionManager transactionManager
        = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(
        entityManagerFactoryBean().getObject() );
      return transactionManager;
   }
}

Cependant, si nous utilisons un projet Spring Boot et que nous avons des dépendances spring-data- * ou spring-tx sur le chemin de classe, la gestion des transactions sera activée par défaut.

3. Configurer les transactions avec XML

Avant 3.1 ou si Java n'est pas une option, voici la configuration XML, en utilisantannotation-driven et le support de l'espace de noms:


   

4. L'annotation@Transactional

Avec les transactions configurées, nous pouvons maintenant annoter un bean avec@Transactional soit au niveau de la classe, soit au niveau de la méthode:

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

L'annotation prend également en chargefurther configuration:

  • lesPropagation Type de la transaction

  • lesIsolation Level de la transaction

  • unTimeout pour l'opération encapsulée par la transaction

  • areadOnly flag - un indice pour le fournisseur de persistance que la transaction doit être en lecture seule

  • les règlesRollback pour la transaction

Notez que - par défaut, l'annulation se produit pour l'exécution, les exceptions non contrôlées uniquement. The checked exception does not trigger a rollback de la transaction. On peut bien entendu configurer ce comportement avec les paramètres d'annotationrollbackFor etnoRollbackFor.

5. Pièges potentiels

5.1. Transactions et procurations

À un niveau élevé,Spring creates proxies for all the classes annotated with @Transactional - soit sur la classe, soit sur l'une des méthodes. Le proxy permet au framework d’injecter une logique transactionnelle avant et après la méthode en cours, principalement pour démarrer et valider la transaction.

Il est important de garder à l’esprit que, si le bean transactionnel implémente une interface, le proxy sera par défaut un proxy dynamique Java. Cela signifie que seuls les appels de méthode externes entrés via le proxy seront interceptés. Any self-invocation calls will not start any transaction, même si la méthode a l'annotation@Transactional.

Une autre mise en garde concernant l'utilisation de proxys est que les méthodesonly public methods should be annotated with @Transactional. de toute autre visibilité ignorent simplement l'annotation en silence car elles ne sont pas mandatées.

5.2. Modification du niveau d'isolement

Nous pouvons également modifier le niveau d'isolation de la transaction:

@Transactional(isolation = Isolation.SERIALIZABLE)

Notez que c'était en faitintroduced au printemps 4.1; si nous exécutons l'exemple ci-dessus avant Spring 4.1, cela entraînera:

org.springframework.transaction.InvalidIsolationLevelException: JPA standard ne prend pas en charge les niveaux d'isolation personnalisés - utilisez unJpaDialect spécial pour votre implémentation JPA

5.3. Transactions en lecture seule

L'indicateurreadOnly génère généralement de la confusion, en particulier lorsque vous travaillez avec JPA; depuis le Javadoc:

Cela sert simplement d'indication pour le sous-système de transaction réel; cela entraîneranot necessarily l'échec des tentatives d'accès en écriture. Un gestionnaire de transactions qui ne peut pas interpréter l'indication en lecture seule lanceranot une exception quand on lui demandera une transaction en lecture seule.

Le fait est quewe can’t be sure that an insert or update will not occur when the readOnly flag is set. Ce comportement dépend du fournisseur, alors que JPA est indépendant du fournisseur.

Il est également important de comprendre quethe readOnly flag is only relevant inside a transaction. Si une opération se produit en dehors d'un contexte transactionnel, l'indicateur est simplement ignoré. Un exemple simple appelant une méthode annotée avec:

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

à partir d'un contexte non transactionnel - une transaction ne sera pas créée et l'indicateurreadOnly sera ignoré.

5.4. Journalisation des transactions

Une méthode utile pour comprendre les problèmes liés aux transactions consiste à ajuster la journalisation dans les packages transactionnels. Le package correspondant au printemps est «org.springframework.transaction”, which should be configured with a logging level of TRACE.

6. Conclusion

Nous avons couvert la configuration de base de la sémantique transactionnelle en utilisant à la fois Java et XML, comment utiliser@Transactional et les meilleures pratiques d'une stratégie transactionnelle.

Comme toujours, le code présenté dans cet article est disponibleover on Github.