Springのデータアクセス(未完)

開発

Springドキュメントのココらへんを途中まで適当に翻訳。
抱えていた問題は解決したっぽいので次に記載。

Part 4 データアクセス

このパートではデータアクセスおよびデータアクセス層とのビジネス層の連携について記述します。
Springの包括的なトランザクション管理サポートは様々なデータアクセスフレームワークを完璧にサポートしています。

11.トランザクション管理

11.1 Spring Frameworkのトランザクション管理の導入

Spring Frameworkはトランザクション管理の一貫した抽象化を行っており、それによって下記のメリットがもたらされます。

  • 一貫したプログラミングモデルを異なるトランザクションAPIに用いることができる(JTA,JDBC,Hibernate,JPA,JDOなど)
  • 宣言的トランザクション管理のサポート
  • プログラマティックトランザクション管理の簡潔なAPI
  • Springのデータアクセス抽象化による素晴らしい開発

11.2 Spring Frameworkのトランザクションサポートモデルの利点

伝統的に、Java EEの開発者はトランザクション管理に2つの選択肢を有していました。「グローバル」もしくは「ローカル」トランザクションの2つで、この両方ともに制約があります。

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

グローバルトランザクションは複数のトランザクションリソースを使用することができるようになります。アプリケーション・サーバーはグローバルトランザクションを(主に例外モデルのせいで)扱いにくいAPIであるJTAで管理しなければなりません。

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

ローカルトランザクションは特定のリソースに特化しており、扱いやすいものの複数のトランザクションリソースを使用することはできません。

11.2.3 Spring Frameworkの一貫したプログラミングモデル

Springはグローバル/ローカルトランザクションの欠点を克服しました。どのような環境でも一貫したプログラミングモデルを提供します。一度書いたコードは別の環境でも動きます。宣言的トランザクションとプログラマティックトランザクションに対応しています。

11.3 Spring Frameworkのトランザクション抽象化の理解

Springのトランザクション抽象化の鍵はトランザクションストラテジーの概念にあります。
トランザクションストラテジーはorg.springframework.transaction.PlatformTransactionManagerインターフェースに定義されています。

public interface PlatformTransactionManager {

    TransactionStatus getTransaction(
            TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;
}

これはプログラム中で使用することもできますが、第一義的にはサービスプロバイダインターフェース(SPI)です。PlatformTransactionManagerはインターフェースであるため、必要に応じてモック化やスタブ化が簡単にできます。

Springの哲学に従い、PlatformTransactionManagerから投げられるTransactionExceptionは非チェック例外です。トランザクションインフラの以上はほとんどは回復不可能であるためです。

getTransactionメソッドはTransactionDefinitionパラメータの応じたTransactionStatusオブジェクトを返します。TransactionStatusは新しいトランザクションのものかもしれないし、現存するトランザクションかもしれません。

TransactionDefinitionインターフェースは下記を規定します。

  • 独立性:このトランザクションが他のトランザクションから独立しているか。例えば、コミットされていない他のトランザクションを参照しているか
  • プロパゲーション:普通は、トランザクション内で実行されるコードはトランザクションの範囲内で影響を及ぼしますが、既に存在するトランザクションに影響を与える事もできます。例えば、既存のトランザクションが存在する中で実行し続けることもできますし、既存のトランザクションを休止させて新たなトランザクションを作成したりすることもできます。
  • タイムアウト:タイムアウトしてロールバックされるまでの時間を定義できます。
  • 読取専用:データを修正しない場合に用います。特にHibernateを使用している際などに最適化が行われます。
public interface TransactionStatus extends SavepointManager {

    boolean isNewTransaction();

    boolean hasSavepoint();

    void setRollbackOnly();

    boolean isRollbackOnly();

    void flush();

    boolean isCompleted();

}

宣言的トランザクション管理を使用しようとプログラマティックトランザクション管理を使用しようと、PlatformTransactionManagerの実装が絶対的に重要です。実装はDIを使用して行えます。

PlatformTransactionManagerの実装には実行環境の情報が必要です。JDBC, JTA, Hibernateなどです。下記の例はJDBCを元にした実装です。

JDBCのDataSourceを定義します。


    
    
    
    

そして、PlatformTransactionManagerのbean定義はDataSourceへの参照を有します。


    

(中略)

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

11.5.1 Spring Frameworkの宣言的トランザクション管理実装の理解

@Transactionalをクラスに追加し、@EnableTransactionManagementをコンフィグレーションに追加することだけを教えても、なぜこれが動くのかを理解してはもらえないでしょう。このセクションでは、 Spring Frameworkの宣言的トランザクションの内部動作について説明します。

もっとも重要なコンセプトは、このサポートがAOPプロキシを利用して行われており、アドバイスがメタデータで動作しているということです。

(中略)

11.5.6 @Transactionalの利用

XMLベースのトランザクション設定に加えて、アノテーションベースのアプローチも利用できます。

下記のように簡単に利用できます。

// the service class that we want to make transactional
@Transactional
public class DefaultFooService implements FooService {

    Foo getFoo(String fooName);

    Foo getFoo(String fooName, String barName);

    void insertFoo(Foo foo);

    void updateFoo(Foo foo);
}

コメント

タイトルとURLをコピーしました