この記事では主に Spring での @Transactional の詳細な使用法に関する関連情報を紹介しますので、必要な方は参考にしてください
Spring での @Transactional の使用法を詳しく紹介します
概要: @Transactional はコントロール トランザクション管理を提供します。 in spring はショートカット方法ですが、多くの人は @Transactional を使用するだけで、各構成項目の使用方法を深く理解していません。この記事では、各構成項目の使用方法を詳しく説明します。
1. @Transactional の定義
Spring の @Transactional は、開発中に発生した問題を便利かつ迅速に解決するための透過的なトランザクション管理メカニズムを提供する動的プロキシ メカニズムに基づいています。実際には、実際の問題は予想よりもはるかに複雑であることが多く、複雑な問題に対処するには @Transactional を深く理解する必要があります。
まず、@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'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 {}; }
ソース コードに基づくと、@Transactional には、複雑なアプリケーションを実現するために構成できる非常に多くの属性があることがわかります。コントロール。各属性の具体的な使い方と機能については、この記事の後半で 1 つずつ説明していきます。
2. @Transactional を使用した Spring 設定
@Transactional に基づくトランザクション管理を使用するには、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 は、 Spring 構成ファイル ソース オブジェクト インスタンス EntityManagerFactory は、JPA で使用されるエンティティ クラス マネージャー org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean に基づいています。これらはデータベースとの接続情報を設定するために使用されます。本質的に、@Transactional はトランザクション制御に JDBC トランザクションを使用します。
3. @Transactional
の値 ここでの値は主に、異なるトランザクション マネージャーを指定するために使用され、同じシステム内の異なるトランザクション マネージャーのニーズを満たすために使用されます。たとえば、Spring では 2 つのトランザクション マネージャー、txManager1 と txManager2 が宣言されています
その後、ユーザーは必要に応じてこのパラメーターを使用して特定の txManager を指定できます
次に、どのような状況で複数のトランザクション マネージャーが存在するのかを尋ねる学生もいます。状況はどうですか? たとえば、複数のデータ ソースまたは複数のデータベースにアクセスする必要があるシステムでは、必然的に複数のトランザクション マネージャーが構成されます。 An4. @Transactional Propagation
Propagation は 7 つの異なる通信メカニズムをサポートします:
ビジネス メソッドが実行されている場合は、トランザクションに参加する必要があります。それ以外の場合は、新しいトランザクションを自分で作成します。これが Spring のデフォルトの伝播動作です。
サポート:
ビジネス メソッドがトランザクション スコープ内で呼び出された場合、そのメソッドはトランザクションの一部となり、ビジネス メソッドがトランザクション スコープ外で呼び出された場合、メソッドはトランザクションなしで実行されます。
必須:
ビジネス メソッドは、既存のトランザクション内でのみ実行できます。トランザクションのない環境でビジネス メソッドが呼び出された場合、例外がスローされます。
ビジネス メソッドは常に、そのメソッドがトランザクション内ですでに実行されている場合、元のトランザクションは一時停止され、新しいトランザクションが作成されます。新しいトランザクションは終了し、元のトランザクションは実行を再開します。t not_supported
如果一个活动的事务存在,则运行在一个嵌套的事务中.如果没有活动的事务,则按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'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)!