Heim  >  Artikel  >  Java  >  Detaillierte Einführung in die Verwendung von @Transactional im Frühjahr

Detaillierte Einführung in die Verwendung von @Transactional im Frühjahr

黄舟
黄舟Original
2017-03-07 10:31:202161Durchsuche

In diesem Artikel werden hauptsächlich relevante Informationen zur detaillierten Verwendung von @Transactional im Frühjahr vorgestellt. Freunde, die sie benötigen, können sich auf

Detaillierte Einführung in die Verwendung von @Transactional im Frühjahr

Einführung: @Transactional bietet eine schnelle Möglichkeit, die Transaktionsverwaltung im Frühjahr zu steuern, aber viele Leute verwenden einfach @Transactional und haben kein tiefes Verständnis für die Verwendung der einzelnen Konfigurationselemente. In diesem Artikel wird die Verwendung der einzelnen Konfigurationen erläutert Artikel ausführlich.

1. Definition von @Transactional

@Transactional in Spring basiert auf dem dynamischen Proxy-Mechanismus, der einen transparenten Transaktionsverwaltungsmechanismus bietet, um das Problem zu erleichtern und schnell zu lösen der aufgetretenen Entwicklungsprobleme. In der Realität sind tatsächliche Probleme oft viel komplexer als wir erwartet haben, was ein tiefgreifendes Verständnis von @Transactional erfordert, um mit komplexen Problemen umgehen zu können.

Schauen wir uns zunächst die Codedefinition von @Transactional an:

@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 {}; 
 
}

Basierend auf dem Quellcode können wir das finden In @Transactional stellt sich heraus, dass es so viele Eigenschaften gibt, die konfiguriert werden können, um eine komplexe Anwendungssteuerung zu erreichen. Die spezifische Verwendung und Funktion jedes Attributs wird später in diesem Artikel einzeln erläutert und erklärt.


2. Spring-Konfiguration mit @Transactional

Um die Transaktionsverwaltung auf Basis von @Transactional zu nutzen, muss die folgende Konfiguration in Spring durchgeführt werden:

 <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 ist eine Objektinstanz der in der Spring-Konfigurationsdatei definierten Datenquelle. EntityManagerFactory ist ein Entity-Klassenmanager basierend auf JPA: org.springframework. orm. jpa.LocalContainerEntityManagerFactoryBean. Diese werden verwendet, um die Verbindungsinformationen mit der Datenbank zu konfigurieren. Im Wesentlichen verwendet @Transactional JDBC-Transaktionen zur Transaktionssteuerung.


Die Deklaration des 2c9e182d80bb0e092d1da29bee424e33-Tags ermöglicht @Transactional innerhalb von Spring für die Transaktionsverwaltung, ähnlich wie bei Anweisungen wie Schaltern.

3. @Transaktionswert

Der Wert wird hier hauptsächlich zur Angabe verschiedener Transaktionsmanager verwendet. Beispielsweise werden in Spring zwei Transaktionsmanager, txManager1 und txManager2, deklariert.

Anschließend können Benutzer diesen Parameter verwenden, um bei Bedarf einen bestimmten txManager anzugeben.

Die Situation ist: Was ist, wenn mehrere Transaktionsmanager vorhanden sind? Beispielsweise werden in einem System, das auf mehrere Datenquellen oder mehrere Datenbanken zugreifen muss, zwangsläufig mehrere Transaktionsmanager konfiguriert.

4. @Transactional propagation

Propagation unterstützt 7 verschiedene Propagationsmechanismen:

ERFORDERLICH

Geschäftsmethoden müssen in einer Transaktion ausgeführt werden, wenn sie ausgeführt werden. Nehmen Sie an der Transaktion teil. Andernfalls erstellen Sie selbst eine neue Transaktion.


UNTERSTÜTZT:

Wenn die Geschäftsmethode innerhalb eines Transaktionsbereichs aufgerufen wird, wird die Methode Teil der Transaktion Wird die Methode im Rahmen einer Transaktion aufgerufen, wird sie Teil der Transaktion. Wenn sie außerhalb des Transaktionsbereichs aufgerufen wird, wird die Methode in einer Umgebung ohne Transaktion ausgeführt.


OBLIGATORISCH:

Kann nur in einer bestehenden Transaktion ausgeführt werden, wenn die Geschäftsmethode dies nicht tut eine Transaktion haben, wird beim Aufruf in einer Umgebung eine Ausnahme ausgelöst


REQUIRES_NEW

Die Geschäftsmethode initiiert immer eine neue Transaktion für sich , wenn die Methode bereits in einer Transaktion ausgeführt wurde, wird die ursprüngliche Transaktion angehalten und eine neue Transaktion erstellt. Die neue Transaktion wird erst beendet, wenn die Methode beendet ist, und die ursprüngliche Transaktion wird fortgesetzt


NOT_SUPPORTED

Das Deklarieren einer Methode erfordert eine Transaktion. Wenn die Methode nicht mit einer Transaktion verknüpft ist, öffnet der Container keine Transaktion dafür Bei einer Transaktion wird die Transaktion ausgesetzt, nachdem der Anruf abgeschlossen ist. Die ursprüngliche Transaktion wird NIEMALS fortgesetzt Die deklarierte Methode darf nicht innerhalb des Transaktionsbereichs ausgeführt werden. Wenn die Methode innerhalb eines bestimmten Transaktionsbereichs ausgeführt wird, wird sie nur dann normal ausgeführt, wenn sie nicht mit einer Transaktion verknüpft ist


VERSCHACHTELT:

          如果一个活动的事务存在,则运行在一个嵌套的事务中.如果没有活动的事务,则按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)!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn