Maison  >  Article  >  Java  >  Introduction détaillée à l'utilisation de @Transactional au printemps

Introduction détaillée à l'utilisation de @Transactional au printemps

黄舟
黄舟original
2017-03-07 10:31:202221parcourir

Cet article présente principalement des informations pertinentes sur l'utilisation détaillée de @Transactional au printemps. Les amis qui en ont besoin peuvent se référer à

Introduction détaillée de l'utilisation de @Transactional au printemps

<.>Introduction : @Transactional fournit un moyen rapide de contrôler la gestion des transactions au printemps, mais de nombreuses personnes utilisent simplement @Transactional et n'ont pas une compréhension approfondie de la façon d'utiliser chaque élément de configuration. Cet article expliquera l'utilisation de chaque configuration. article en profondeur.

1. Définition de @Transactional

@Transactional in Spring est basé sur le mécanisme de proxy dynamique, qui fournit un mécanisme de gestion transparent des transactions pour faciliter et résoudre rapidement le problème. des problèmes de développement rencontrés. En réalité, les problèmes réels sont souvent beaucoup plus complexes que prévu, ce qui nécessite une compréhension approfondie de @Transactional afin de traiter des problèmes complexes.

Jetons d'abord un coup d'œil à la définition du code de @Transactional :

@Target({ElementType.METHOD, ElementType.TYPE}) 
@Retention(RetentionPolicy.RUNTIME) 
@Inherited 
@Documented 
public @interface Transactional { 
 
  /** 
   * A qualifier value for the specified transaction. 
   * <p>May be used to determine the target transaction manager, 
   * matching the qualifier value (or the bean name) of a specific 
   * {@link org.springframework.transaction.PlatformTransactionManager} 
   * bean definition. 
   */ 
  String value() default ""; 
 
  /** 
   * The transaction propagation type. 
   * Defaults to {@link Propagation#REQUIRED}. 
   * @see org.springframework.transaction.interceptor.TransactionAttribute#getPropagationBehavior() 
   */ 
  Propagation propagation() default Propagation.REQUIRED; 
 
  /** 
   * The transaction isolation level. 
   * Defaults to {@link Isolation#DEFAULT}. 
   * @see org.springframework.transaction.interceptor.TransactionAttribute#getIsolationLevel() 
   */ 
  Isolation isolation() default Isolation.DEFAULT; 
 
  /** 
   * The timeout for this transaction. 
   * Defaults to the default timeout of the underlying transaction system. 
   * @see org.springframework.transaction.interceptor.TransactionAttribute#getTimeout() 
   */ 
  int timeout() default TransactionDefinition.TIMEOUT_DEFAULT; 
 
  /** 
   * {@code true} if the transaction is read-only. 
   * Defaults to {@code false}. 
   * <p>This just serves as a hint for the actual transaction subsystem; 
   * it will <i>not necessarily</i> cause failure of write access attempts. 
   * A transaction manager which cannot interpret the read-only hint will 
   * <i>not</i> throw an exception when asked for a read-only transaction. 
   * @see org.springframework.transaction.interceptor.TransactionAttribute#isReadOnly() 
   */ 
  boolean readOnly() default false; 
 
  /** 
   * Defines zero (0) or more exception {@link Class classes}, which must be a 
   * subclass of {@link Throwable}, indicating which exception types must cause 
   * a transaction rollback. 
   * <p>This is the preferred way to construct a rollback rule, matching the 
   * exception class and subclasses. 
   * <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(Class clazz)} 
   */ 
  Class<? extends Throwable>[] rollbackFor() default {}; 
 
  /** 
   * Defines zero (0) or more exception names (for exceptions which must be a 
   * subclass of {@link Throwable}), indicating which exception types must cause 
   * a transaction rollback. 
   * <p>This can be a substring, with no wildcard support at present. 
   * A value of "ServletException" would match 
   * {@link javax.servlet.ServletException} and subclasses, for example. 
   * <p><b>NB: </b>Consider carefully how specific the pattern is, and whether 
   * to include package information (which isn&#39;t mandatory). For example, 
   * "Exception" will match nearly anything, and will probably hide other rules. 
   * "java.lang.Exception" would be correct if "Exception" was meant to define 
   * a rule for all checked exceptions. With more unusual {@link Exception} 
   * names such as "BaseBusinessException" there is no need to use a FQN. 
   * <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(String exceptionName)} 
   */ 
  String[] rollbackForClassName() default {}; 
 
  /** 
   * Defines zero (0) or more exception {@link Class Classes}, which must be a 
   * subclass of {@link Throwable}, indicating which exception types must <b>not</b> 
   * cause a transaction rollback. 
   * <p>This is the preferred way to construct a rollback rule, matching the 
   * exception class and subclasses. 
   * <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(Class clazz)} 
   */ 
  Class<? extends Throwable>[] noRollbackFor() default {}; 
 
  /** 
   * Defines zero (0) or more exception names (for exceptions which must be a 
   * subclass of {@link Throwable}) indicating which exception types must <b>not</b> 
   * cause a transaction rollback. 
   * <p>See the description of {@link #rollbackForClassName()} for more info on how 
   * the specified names are treated. 
   * <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(String exceptionName)} 
   */ 
  String[] noRollbackForClassName() default {}; 
 
}

Sur la base du code source, nous pouvons trouver que dans @Transactional, il s'avère qu'il existe de nombreuses propriétés qui peuvent être configurées pour obtenir un contrôle d'application complexe. L'utilisation et la fonction spécifiques de chaque attribut seront expliquées et expliquées un par un plus loin dans cet article.


2. Configuration Spring à l'aide de @Transactional

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

 <beans:bean id="transactionManager" 
  class="org.springframework.orm.jpa.JpaTransactionManager"> 
  <beans:property name="dataSource" ref="dataSource" /> 
  <beans:property name="entityManagerFactory" ref="entityManagerFactory" /> 
</beans:bean> 
 
<!-- 声明使用注解式事务 --> 
<tx:annotation-driven transaction-manager="transactionManager" />

DataSource est une instance d'objet de la source de données définie dans le fichier de configuration Spring EntityManagerFactory est un gestionnaire de classes d'entités basé sur JPA : org.springframework. orm.jpa.LocalContainerEntityManagerFactoryBean. Ceux-ci sont utilisés pour configurer les informations de connexion avec la base de données. Essentiellement, @Transactional utilise les transactions JDBC pour le contrôle des transactions.


La déclaration de la balise 2c9e182d80bb0e092d1da29bee424e33 active @Transactional dans Spring pour la gestion des transactions, similaire aux instructions telles que les commutateurs.

3. @Valeur transactionnelle

la valeur ici est principalement utilisée pour spécifier différents gestionnaires de transactions principalement utilisés pour satisfaire le besoin de différentes transactions dans le même gestionnaire de système ; Par exemple, au Spring, deux gestionnaires de transactions, txManager1 et txManager2, sont déclarés

Ensuite, les utilisateurs peuvent utiliser ce paramètre pour spécifier un txManager spécifique selon leurs besoins.

Certains étudiants demanderont ce qu'il en est. La situation est la suivante : "Que se passe-t-il s'il y a plusieurs gestionnaires de transactions ?" Par exemple, dans un système devant accéder à plusieurs sources de données ou à plusieurs bases de données, plusieurs gestionnaires de transactions seront inévitablement configurés.

4. @Propagation transactionnelle

La propagation prend en charge 7 mécanismes de propagation différents :

OBLIGATOIRE

Les méthodes métier doivent s'exécuter dans une transaction. Si la méthode est déjà dans une transaction lors de son exécution, rejoignez la transaction, sinon créez vous-même une nouvelle transaction. C'est le comportement de propagation par défaut de Spring.


SUPPORTS :

Si la méthode métier est appelée dans une portée de transaction, la méthode devient une partie de la transaction. appelée dans le cadre d'une transaction, la méthode devient une partie de la transaction. Si elle est appelée en dehors de la portée de la transaction, la méthode est exécutée dans un environnement sans transaction.


OBLIGATOIRE :

Ne peut être exécuté que dans une transaction existante. La méthode commerciale ne peut pas lancer sa propre transaction si la méthode commerciale ne le fait pas. avoir une transaction, lorsqu'elle est appelée dans un environnement, une exception est levée


REQUIRES_NEW

La méthode métier lancera toujours une nouvelle transaction pour elle-même , si la méthode a déjà été exécutée dans une transaction, la transaction d'origine est suspendue et une nouvelle transaction est créée. La nouvelle transaction ne se terminera pas tant que la méthode n'est pas terminée et la transaction d'origine reprendra l'exécution


<.>

NOT_SUPPORTED


La déclaration d'une méthode nécessite une transaction. Si la méthode n'est pas associée à une transaction, le conteneur n'ouvrira pas de transaction pour elle. dans une transaction, la transaction sera suspendue. Une fois l'appel terminé, la transaction originale reprendra l'exécution


JAMAIS :


Le. La méthode déclarée ne doit pas être exécutée dans la portée de la transaction.Si la méthode Lorsqu'elle est exécutée dans une certaine portée de transaction, le conteneur lèvera une exception Seulement lorsqu'il n'est pas associé à une transaction, il s'exécutera normalement

.

Imbriqué :


          如果一个活动的事务存在,则运行在一个嵌套的事务中.如果没有活动的事务,则按REQUIRED属性执行.它使用了一个单独的事务, 这个事务拥有多个可以回滚的保证点.内部事务回滚不会对外部事务造成影响, 它只对DataSourceTransactionManager 事务管理器起效.

     其实大家最感到困惑的是REQUIRED_NEW和NESTED两种不同的传播机制,功能类似,都涉及到了事务嵌套的问题,那两者有何区别呢?该如何正确使用这两种模式呢?

        以下是摘自Spring的文档:

  PROPAGATION_REQUIRES_NEW : uses a completely independent transaction for
 each affected transaction scope. In that case, the underlying physical 
transactions are different and hence can commit or roll back independently, 
with an outer transaction not affected by an inner transaction&#39;s rollback status.

         内部的事务独立运行,在各自的作用域中,可以独立的回滚或者提交;而外部的事务将不受内部事务的回滚状态影响。   

 ROPAGATION_NESTED : uses a single physical transaction with multiple 
savepoints that it can roll back to. Such partial rollbacks allow an
 inner transaction scope to trigger a rollback for its scope, with the outer 
transaction being able to continue the physical transaction despite some operations 
having been rolled back. This setting is typically mapped onto JDBC savepoints, so will 
only work with JDBC resource transactions.

       NESTED的事务,基于单一的事务来管理,提供了多个保存点。这种多个保存点的机制允许内部事务的变更触发外部事务的回滚。而外部事务在混滚之后,仍能继续进行事务处理,即使部分操作已经被混滚。 由于这个设置基于JDBC的保存点,所以只能工作在JDBC的机制智商。

       由此可知, 两者都是事务嵌套,不同之处在于,内外事务之间是否存在彼此之间的影响;NESTED之间会受到影响,而产生部分回滚,而REQUIRED_NEW则是独立的。

 以上就是Spring中@Transactional用法详细介绍的内容,更多相关内容请关注PHP中文网(www.php.cn)!

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