SpringとJPAを使用したトランザクション
1. 概要
このチュートリアルでは、the right way to configure Spring Transactions、@Transactionalアノテーションの使用方法、および一般的な落とし穴について説明します。
コア永続性構成の詳細については、Spring with JPA tutorialを確認してください。
基本的に、トランザクションを構成するには、アノテーションとAOPの2つの異なる方法があり、それぞれに利点があります。 ここでは、より一般的なannotation-configについて説明します。
参考文献:
Spring BootからのHibernate / JPA SQLステートメントの表示
Spring Bootアプリケーションで生成されたSQLステートメントのロギングを構成する方法を学びます。
2. XMLなしでトランザクションを構成する
Spring 3.1では、@Configurationクラスで使用してトランザクションサポートを有効にできるthe @EnableTransactionManagement annotationが導入されています。
@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{
@Bean
public LocalContainerEntityManagerFactoryBean
entityManagerFactoryBean(){
//...
}
@Bean
public PlatformTransactionManager transactionManager(){
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
entityManagerFactoryBean().getObject() );
return transactionManager;
}
}
ただし、Spring Bootプロジェクトを使用していて、クラスパスにspring-data- *またはspring-txの依存関係がある場合、トランザクション管理はデフォルトで有効になります。
3. XMLを使用したトランザクションの構成
3.1より前、またはJavaがオプションでない場合は、annotation-drivenと名前空間サポートを使用したXML構成を次に示します。
4. @Transactional注釈
トランザクションが構成されたら、クラスレベルまたはメソッドレベルでBeanに@Transactionalのアノテーションを付けることができます。
@Service
@Transactional
public class FooService {
//...
}
注釈はfurther configurationもサポートします。
-
トランザクションのPropagation Type
-
トランザクションのIsolation Level
-
トランザクションによってラップされた操作のTimeout
-
readOnly flag –トランザクションを読み取り専用にする必要があるという永続性プロバイダーへのヒント
-
トランザクションのRollbackルール
-デフォルトでは、ロールバックは実行時の未チェックの例外に対してのみ発生することに注意してください。 トランザクションのThe checked exception does not trigger a rollback。 もちろん、rollbackForおよびnoRollbackFor注釈パラメーターを使用してこの動作を構成できます。
5. 潜在的な落とし穴
5.1. トランザクションとプロキシ
高レベルでは、Spring creates proxies for all the classes annotated with @Transactional –クラスまたは任意のメソッドのいずれか。 プロキシにより、フレームワークは、主にトランザクションの開始とコミットのために、実行中のメソッドの前後にトランザクションロジックを挿入できます。
覚えておくべき重要なことは、トランザクションBeanがインターフェースを実装している場合、デフォルトではプロキシはJava動的プロキシになるということです。 これは、プロキシを介して着信する外部メソッド呼び出しのみがインターセプトされることを意味します。 メソッドに@Transactionalアノテーションがある場合でも、Any self-invocation calls will not start any transaction,。
プロキシを使用する場合のもう1つの注意点は、他の可視性のonly public methods should be annotated with @Transactional.メソッドは、プロキシされていないため、アノテーションを黙って無視することです。
5.2. 分離レベルの変更
トランザクション分離レベルも変更できます。
@Transactional(isolation = Isolation.SERIALIZABLE)
これは実際にはSpring4.1ではintroducedであることに注意してください。 Spring 4.1より前に上記の例を実行すると、次のようになります。
org.springframework.transaction.InvalidIsolationLevelException:標準JPAはカスタム分離レベルをサポートしていません– JPA実装には特別なJpaDialectを使用してください
5.3. 読み取り専用トランザクション
readOnlyフラグは通常、特にJPAを使用する場合に、混乱を引き起こします。 Javadocから:
これは、実際のトランザクションサブシステムのヒントとして機能します。 not necessarilyにより、書き込みアクセスの試行が失敗します。 読み取り専用ヒントを解釈できないトランザクションマネージャーは、読み取り専用トランザクションを要求されると、notで例外をスローします。
事実、we can’t be sure that an insert or update will not occur when the readOnly flag is set.この動作はベンダーに依存しますが、JPAはベンダーに依存しません。
the readOnly flag is only relevant inside a transaction.操作がトランザクションコンテキストの外部で発生した場合、フラグは単に無視されることを理解することも重要です。 その簡単な例では、次のアノテーションが付けられたメソッドを呼び出します。
@Transactional( propagation = Propagation.SUPPORTS,readOnly = true )
非トランザクションコンテキストから–トランザクションは作成されず、readOnlyフラグは無視されます。
5.4. トランザクションログ
トランザクション関連の問題を理解するための便利な方法は、トランザクションパッケージのロギングを微調整することです。 Springの関連パッケージは「org.springframework.transaction”, which should be configured with a logging level of TRACE.」です。
6. 結論
JavaとXMLの両方を使用したトランザクションセマンティクスの基本構成、@Transactionalの使用方法、およびトランザクション戦略のベストプラクティスについて説明しました。
いつものように、この記事で紹介されているコードはover on Githubで利用できます。