Maison  >  Article  >  Java  >  Introduction détaillée aux exemples d'annulation de transactions @Transactional et au code source au printemps (photo)

Introduction détaillée aux exemples d'annulation de transactions @Transactional et au code source au printemps (photo)

黄舟
黄舟original
2017-03-30 11:00:592114parcourir

1. Exemples de scénarios d'utilisation

Avant de comprendre comment utiliser @Transactional, il faut d'abord savoir à quoi sert @Transactional. Voici un exemple : par exemple, il y a de nombreux membres dans un département, qui sont stockés respectivement dans la table des départements et la table des membres. Lorsque supprime un département, supposons que nous supprimons les membres correspondants par défaut. Cependant, cette situation peut se produire lors de l'exécution. Nous supprimons d'abord le département, puis supprimons les membres. Cependant, le département est supprimé avec succès, mais une exception se produit lors de la suppression des membres. Pour le moment, nous espérons que si la suppression du membre échoue, les départements précédemment supprimés seront également restaurés. Dans ce scénario, vous pouvez utiliser la restauration des transactions @Transactional.

2. Exceptions vérifiées et exceptions non vérifiées

La raison pour laquelle tout le monde est clair sur les concepts d'exceptions vérifiées et d'exceptions non vérifiées est parce que :

Spring utilise une transaction déclarative. traitement , par défaut, si une exception non vérifiée se produit dans la méthode annotée Opération de base de données, toutes les opérations de base de données seront annulées ; si l'exception qui se produit est une exception vérifiée, l'opération de base de données sera toujours soumise par défaut.

exception cochée :

signifie invalide et ne peut pas être prédit dans le programme. Par exemple, entrée utilisateur non valide, fichier n'existe pas, erreur de lien réseau ou base de données. Ce sont toutes des raisons externes et ne peuvent pas être contrôlées au sein du programme.

doit être géré explicitement dans le code. Par exemple, effectuez un traitement de bloc try-catch ou ajoutez une description de lancement à la méthode pour lever l'exception vers la couche supérieure de la pile d'appels.

Hérite de java.lang.Exception (sauf java.lang.RuntimeException).

exception non cochée :

indique une erreur, une erreur logique dans le programme. Est une sous-classe de RuntimeException, telle que IllegalArgumentException, NullPointerException et IllegalStateException.

Il n'est pas nécessaire d'intercepter explicitement les exceptions non vérifiées dans le code pour la gestion.

Hérite de java.lang.RuntimeException (et java.lang.RuntimeException hérite de java.lang.Exception).

Regardez le diagramme de structure des exceptions ci-dessous, qui peut avoir un sens plus profond de la hiérarchie :

Introduction détaillée aux exemples dannulation de transactions @Transactional et au code source au printemps (photo)

Exemples d'utilisation de @Transactional

Cet exemple utilise It is

Eclipse+maven. Maven n'est géré que comme un pot. Même ceux qui ne comprennent pas Maven peuvent le comprendre.

3.1. Le fichier de configuration de Spring

doit d'abord configurer l'espace de noms tx comme suit :

Introduction détaillée aux exemples dannulation de transactions @Transactional et au code source au printemps (photo)

Afin d'utiliser la gestion des transactions basée sur @Transactional, la configuration suivante doit être effectuée dans Spring :

<bean id="appTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:annotation-driven proxy-target-class="false" transaction-manager="appTransactionManager" />
L'intégralité du fichier de configuration Spring du blogueur :




       
     
        
            
               classpath:properties/*.properties
                
            
        
    

    
    
        
        
       
        
            ${jdbc_driverClassName}
        
        
            ${jdbc_url}
        
        
            ${jdbc_username}
        
        
            ${jdbc_password}
        
    

    <bean id="appTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:annotation-driven proxy-target-class="false" transaction-manager="appTransactionManager" />

    
    
        
    

    
    
        
          
        
        
    

    
    

3.2. Utilisez @Transactional, ajoutez la méthode de classe d'implémentation user dans et ajoutez une annotation

@Transactional(propagation=Propagation.REQUIRED)
public void addUser(User user) {
    userDao.addUser(user);
    String string  = null;
    if(string.equals("")) {
        int i = 0;
    }
}
J'ai délibérément provoqué une exception de pointeur nul dans la méthode ci-dessus, ce qui fera reculer les choses

3.3 Exécutez la classe test unitaire

@Test  
public void addUserTest(){  
    User user = new User();
    user.setUserName("luoguohui1");
    user.setUserPassword("luoguohui1");
    userService.addUser(user);
}
et constatez qu'elle ne peut pas être insérée, mais si @Transactional est supprimé, le code est le suivant, bien qu'une exception se produise, mais les données correspondantes sont toujours ajoutées à la base de données :

Introduction détaillée aux exemples dannulation de transactions @Transactional et au code source au printemps (photo)

3.4, code source télécharger

Le projet de cet article est dans mybatis Modifié sur la base du Getting Started (y compris des exemples de didacticiels et de code source), cet article contient le processus détaillé des scripts de base de données et de la construction du projet.

4. Concepts que vous devez comprendre à propos de @Transactional in Spring

@Transactional in Spring est basé sur le mécanisme de proxy dynamique, qui fournit un mécanisme de gestion des transactions transparent, pratique et rapide à utiliser. résoudre lors du développement les problèmes rencontrés.

L'utilisation générale consiste à annoter des méthodes ou des interfaces ou des classes

via le code suivant :

@Transactional(propagation=Propagation.NOT_SUPPORTED)
La propagation prend en charge 7 mécanismes de propagation différents :

OBLIGATOIRE : Si une transaction existe, la transaction en cours est prise en charge. S'il n'y a pas de transaction, démarrez une nouvelle transaction.

SUPPORTS : Si une transaction existe, prenez en charge la transaction en cours. S'il n'y a pas de transaction, alors exécution sans transaction. Mais pour les gestionnaires de transactions avec synchronisation des transactions, PROPAGATION_SUPPORTS est légèrement différent de ne pas utiliser de transactions.

NOT_SUPPORTED : exécutez toujours de manière non transactionnelle et suspendez toutes les transactions existantes.

REQUIRESNEW : démarrez toujours une nouvelle transaction. Si une transaction existe déjà, la transaction existante est suspendue.

OBLIGATOIRE : Si une transaction existe déjà, la transaction en cours est prise en charge. S'il n'y a pas de transaction active,

lève une exception .

JAMAIS : exécutez toujours de manière non transactionnelle, si une transaction active existe, lancez une exception.

NESTED : si une transaction active existe, exécutez-la dans une transaction imbriquée. S'il n'y a pas de transaction active, exécutez selon REQUIREDpropriété.

Voici quelques points auxquels il faut prêter attention. Vous devez les lire, sinon vous rencontrerez divers pièges, ne dites pas que le blogueur ne vous l'a pas rappelé  :

Voici quelques points auxquels vous devez faire attention. Vous devez les lire. Sinon, ne dites pas que le blogueur ne vous l'a pas rappelé si vous rencontrez divers pièges. >

Voici quelques éléments auxquels vous devez prêter attention. Vous devez les lire. Vous devez les lire, sinon ne dites pas que le blogueur ne vous l'a pas rappelé si vous rencontrez divers pièges

. :

    Ajoutez une annotation @Transactional là où la gestion des transactions est requise. L'annotation @Transactional peut être appliquée aux définitions d'interface et aux méthodes d'interface, aux définitions de classe et aux méthodes publiques de classes.
  • L'annotation @Transactional ne peut être appliquée qu'aux méthodes ayant une visibilité publique. Si vous utilisez l'annotation @Transactional sur une méthode protégée, privée ou visible par le package, elle ne signalera pas d'erreur, mais la méthode annotée n'affichera pas les paramètres de transaction configurés.
  • Notez que la simple apparition de l'annotation @Transactional ne suffit pas à activer le
  • comportement

    de la transaction, il s'agit simplement d'une sorte de métadonnées. Les éléments de configuration doivent être utilisés dans le fichier de configuration pour réellement activer le comportement des transactions.

  • Utilisez la valeur de l'attribut "proxy-target-class" de l'élément pour contrôler si un proxy basé sur une interface ou basé sur une classe est créé. Si la valeur de l'attribut "proxy-target-class" est définie sur "true", alors le proxy basé sur les classes fonctionnera (cela nécessite que la bibliothèque CGLIB cglib.jar soit dans le CLASSPATH). Si la valeur de l'attribut "proxy-target-class" est définie sur "false" ou si cet attribut est omis, alors le proxy standard basé sur l'interface JDK sera utilisé.
  • L'équipe Spring recommande d'utiliser l'annotation @Transactional sur des classes spécifiques (ou des méthodes de classe), plutôt que sur n'importe quelle interface que la classe souhaite implémenter. L'utilisation de l'annotation @Transactional sur une interface ne prendra effet que si vous configurez un proxy basé sur l'interface. Étant donné que les annotations ne sont pas héritables, cela signifie que si vous utilisez un proxy basé sur une classe, les paramètres de transaction ne seront pas reconnus par le proxy basé sur la classe et l'
  • objet

    ne sera pas reconnu par le proxy de transaction. . Emballer.

  • @Une transaction transactionnelle est ouverte ou un proxy basé sur une interface ou basé sur une classe est créé. Par conséquent, si une méthode de la même classe appelle une autre méthode comportant une transaction, celle-ci ne fonctionnera pas.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn