Spring > TransactionManagement

Springトランザクション管理概要

包括的なトランザクション管理

  • さまざまなトランザクションAPIを同じように扱える
  • Springデータアクセスとの統合

グローバルトランザクション

  • JTAを使ってグローバルトランザクションをつかう
  • JTAのUserTransactionはJNDI経由で利用する⇒アプリケーションサーバ外で再利用できない
  • EJB CMTを使うこともできる。
  • CMTはJTAつまりアプリケーションサーバ環境と結びついてしまう
  • CMTを利用するにはビジネスロジックをEJBとして実装しないといけない

ローカルトランザクション

  • 特定のリソースにひもづくトランザクション
  • 複数のトランザクションリソースは扱えない
  • JTAトランザクションは扱えない

Springのトランザクションモデル

  • 一貫していて、どの環境でも動く
    • JTA
    • JDBC
    • Hibernate
    • JPA
    • JDO
  • 宣言的トランザクション管理
    • トランザクション管理に必要なコードをかかなくていい
    • トランザクションのAPIに依存しないコードがかける
    • シンプルなプログラマティックトランザクション管理
    • アプリケーションサーバのトランザクション管理が必要なのは、複数リソースのトランザクションを扱う時くらい

トランザクションモデル要素

  • PlatformTransactionManager
    • トランザクションストラテジ
    • SPI。モックとかスタブとか作れる
    • DataSourceTransactionManager:データソースを参照
    • JtaTransactionManager:JavaEEのJTAのデータソースを使う場合
    • HibernateTransactionManager:Hibernateの場合。LocalSessionFactoryBeanを参照
  • TransactionException
    • 実行時例外だから、必要に応じて例外処理すればいい
  • getTransaction
    • TransactionStatusを取得できる
  • TransactionDefinition
    • 分離レベル
    • Propagation
    • Timeout
    • Read-only status
  • TransactionStatus
    • 実行しているスレッドと関連づいてる
    • トランザクション実行制御とトランザクション情報のクエリ

トランザクションを伴うリソースの同期

High-level synchronization approach

  • リソースの生成、再利用、破棄、リソースのトランザクション同期、例外のマッピング
  • native ORM API
  • JdbcTemplateなどのテンプレート

Low-level synchronization approach

  • ネイティブAPIを使いたい(あんまりないけど)
  • Spring管理のインスタンスの取得、リソースのトランザクション同期、例外のマッピング
  • DataSourceUtils/EntityManagerFactoryUtils/SessionFactoryUtils/PersistenceManagerFactoryUtils

TransactionAwareDataSourceProxy

  • DataSourceのプロキシ
  • 既存のコードがDataSourceをつかっていて、Spring管理のトランザクションに入れたいとき
  • High-level synchronization approachに置き換えるのが正解

宣言的トランザクション管理

  • SpringAOPの技術によって可能になってる。
  • CMTとの比較
    • トランザクションの振る舞いを設定できるのは同じ
    • CMTと違って、JTA以外でもローカルトランザクション(JDBC,JPA...)でも使える
    • EJBとちがって、どんなクラスにでもトランザクション管理をきかせられる
    • ロールバックルールを提供
      • 自動ロールバックする例外を指定できる
      • デフォルトではCMTと同じ動作(非チェック例外ではロールバック、チェック例外ではロールバックしない)
      • ビジネスオブジェクトがトランザクションのことを気にしなくてよくなる
    • トランザクションの振る舞いをAOPを使って変えられる
    • リモートも含めたトランザクションは利用できない
      • そもそも利用することあるか要確認

宣言的トランザクションの中身

  • 宣言的トランザクションはAOPプロキシで実現されている
    • TransactionInterceptor
    • アドバイスとジョインポイントはメタデータで(XML or アノテーション)指定
    • caller⇒AOPプロキシ⇒トランザクションアドバイザ⇒カスタムアドバイザ⇒ターゲットメソッド

ロールバックの宣言的設定

  • デフォルトでは、非チェック例外ではロールバック、チェック例外ではロールバックしない)
  • ロールバックする/しない例外を個別に指定
    <tx:method name="*" rollback-for="Throwable" no-rollback-for="InstrumentNotFoundException"/>
    

ビーン毎にトランザクションの設定を切り替える

  • <aop:advisor>、<aop:pointcut>、<tx:advise>を複数セット用意

<tx:advise/>

  • デフォルト値
    • プロパゲーション=REQUIRED
    • 分離レベル=DEFAULT
    • read/write
    • タイムアウト時間=対象のトランザクションシステムのタイムアウト時間。(タイムアウトがサポートされない場合はなし)
    • RuntimeException⇒ロールバック、それ以外⇒ロールバックしない
  • tx:attributes/tx:method の設定項目
    • name:トランザクションと関連付けられるメソッド名(*利用可能)
    • propagation [REQUIRED]
    • isolation[DEFAULT]
    • timeout[-1]
    • read-only[false]
    • rollback-for
    • no-rollback-for

@Transactional

  • アノテーションでトランザクションの設定ができる
  • 利用できる場所
    • インターフェース定義、インターフェースメソッド、クラス定義、クラスのpublicメソッド
  • <tx:annotation-driven/>と一緒に使う
    • transaction-manager [transactionManager]
    • mode [proxy]
      • aspectjも指定可能
    • proxy-target-class [false]
      • trueの場合は、クラスベースのプロキシ
      • falseの場合は、JDKインターフェースベースのプロキシ
    • order [Ordered.LOWEST_PRECEDENCE]
    • <tx:annotation-driven/>のが設定されたアプリケーションコンテキストのビーンについてのみ@Transactionalが有効
  • クラス定義、またはクラスメソッドのみに利用したほうがいい。
    • アノテーションはインターフェースからは継承されないため、クラスベースのプロキシ、ウィービングベースのアスペクトを使うと、トランザクションが有効にならない
  • プロキシモード(デフォルト)ではセルフインボケーションでは、@Transactionalは効かない
  • AspectJモードでは、セルフインボケーションでも@Transactionalは有効(ウィービングされるから)
  • @Transactionalの優先度 クラスレベル < メソッド
  • @Transactionalの設定項目
    • value
    • propagation
    • isolation
    • readOnly
    • timeout
    • rollbackFor
    • noRollbackFor
  • トランザクション名はFQCN.メソッド名
  • 複数のトランザクションマネージャを使う
    @Transactional("xxx") :xxxはビーン定義の<qualifier/>
    
  • よく使う@Transactionalの属性値のセットがあれば、カスタムアノテーションを作るのがいい

トランザクションプロパゲーション

最終更新:2012年02月29日 17:15
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。