1.はじめに

Springが提供するトランザクション機能を使うためのアプリケーションコンテキストの例を説明します。

次の解説にトランザクション処理の実装例について説明していますのでそちらも参考にして下さい。

(1)springを使う a0204 dtd-AOPを使ったトランザクション処理の例

(2)hibernateを使う hibernate a0303 hibernateを使ったトランザクション処理の例

 

上記の例はproxyを使った方法です。この解説では、Spring2.0の新機能であるスキーマ定義のアプリケーションコンテキストを使った例を示します。比較のためSpring1.2の機能範囲でも使えるproxyを使った方法も紹介します。

この解説ではこの二つの方法を簡単のため次の呼び方をします。

(1)proxy設定方式

    Spring1.2からある機能です。トランザクション処理のために明示的にproxyを設定します。

(2)AOP方式

    Spring2.0で新しくサポートされた機能です。AOPの概念に基づいて、様相(aspect)と勧告(advice)、切込み点(pointcut)を使ってトランザクション処理を設定します。

 

これらは設定する方式を区別するための呼び方です。処理の方法は変わらないと思います。

proxy設定方式も実装はAOPの概念に基づいています。しかし、設定の段階ではAOPの実装が表に現れて、AOPの概念は裏に隠れています。だから、AOPを知らなくても設定は理解できます。

それに対して、AOP方式は設定そのものがAOPの概念に基づいています。逆に実装は裏に隠れています。結果としてproxyは設定の中に出てきません。代わりにAOP独自の様相(aspect)と勧告(advice)、切込み点(pointcut)が設定に中に出てきます。

この解説ではAOPについての解説はしません。一般の資料を参考にして下さい。又は、この解説を理解するだけであれば、次の解説を参考にして下さい。

TODO リンク 解説:SpringのAOPを使う

 

 

2.トランザクション処理の指定

2.1概要

proxy方式のトランザクション処理のクラス(bean)の構成を図2.1-1に示します。

 

図2.1-1 proxyを使ったトランザクション処理のクラス(bean)の構成(p2)

図2.1-1 proxyを使ったトランザクション処理のクラス(bean)の構成

 

特徴は次の通りです。

(1)ClientとTargetの間にproxyを入れます。

(2)トランザクションマネジャはproxyから参照されます。

(3)トランザクション属性もproxyから参照されます。

 

図2.1-2はAOP方式のトランザクション処理の構成です。

 

図2.1-2 proxyを指定しない(*1)方式のトランザクション処理の構成(p2)

図2.1-2 proxyを指定しない(*1)方式のトランザクション処理の構成

 

この特徴は次の通りです。

(1)ClientとTargetとは直結されます(proxyはありません)。

(2)トランザクションマネジャとTx属性は勧告(advice)から参照されます。

(3)勧告(advice)がAdvisorから参照されます。

(4)切込み点(pointcut)はAdvisorから参照されます。

(5)切込み点(pointcut)はTargetが勧告(advice)の対象になる設定になっている。

 

注 proxyの有無は設定の中の相違です。実装にはproxyが使われています。

 

2.2 トランザクション処理の指定法

2.2.1 proxy設定方式

 

リスト2.2-1 proxy設定方式のトランザクション処理設定コード

① <bean id="serviceProxy"
         class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="txManager"/>
    <property name="target" ref="serviceTarget"/>
    <property name="transactionAttributes">
      <props>
        <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
        <prop key="*">PROPAGATION_REQUIRED</prop>
      </props>
    </property>
  </bean>

② <bean id="txManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
  </bean>
  
③ <bean id="client" class="msh.pub.springtx.cmn.impl.Client">
    <property name="service" ref="serviceProxy"/>
  </bean>
④ <bean id="serviceTarget" class="...">
      ...
    </bean>
⑤ <bean id="dataSource"
      ...
  </bean>

①proxyの定義です。ここでトランザクションマネジャとターゲット、トランザクション属性を指定します。

②トランザクションマネジャbeanの定義です。これはAOP方式でも同じです。

③クライアント(serviceを利用するクラス)を定義します。serviceプロパティにproxy beanのid(=serviceProxy)を指定します。この点がAOP方式と異なります。ClientクラスそのものはAOP方式と同じものです。

④Service beanを定義します。このid(=serviceTarget)はproxy beanから参照されています。

Serviceクラス及びService beanの定義そのものはAOP方式と同じです。

⑤DataSource beanの定義です。Serviceクラス及びService beanの定義そのものはAOP方式と同じです。

 

例題を動かすために①~⑤以外にbeanを定義していますがAOP方式の場合と同じです。

 

AOP方式との違いをまとめると、①と③です。

 

2.2.2 AOP方式

 

リスト2.2-2 AOP方式のトランザクション処理設定コード

  <aop:config>
① <aop:pointcut id="servicePointcut"
          expression="execution(* msh.pub.springtx.cmn.IService.*(..))"/>
② <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut"/>
  </aop:config>

③<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
      <tx:method name="find*" propagation="REQUIRED" read-only="true"/>
      <tx:method name="*" propagation="REQUIRED"/>
    </tx:attributes>
  </tx:advice>
④ <bean id="txManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
  </bean>
  
⑤ <bean id="client" class="msh.pub.springtx.cmn.impl.Client">
    <property name="service" ref="serviceTarget"/>
  </bean>
⑥ <bean id="serviceTarget" class="...">
      ...
    </bean>
⑦ <bean id="dataSource"
      ...
  </bean>

①切り込み点(pointcut)を定義します。対象にServiceを含む指定になっています。

②Advisorを定義します。一般のAOPの様相(aspect)に相当すします。Advisorには、勧告(advice)と切込み点(pointcut)をプロパティに設定します。

③トランザクションの処理をする勧告(advice)を定義します。

④トランザクションマネジャを定義します。これはproxy設定方式でも同じです。

⑤Client(Serviceを使うクラス)を定義します。serviceプロパティにService beanのid(=serviceTarget)を指定します。この点がproxy設定方式と異なります。Clientクラスそのものはproxy設定方式と同じものです。

⑥Service beanを定義します。proxy設定方式と違って、このbeanはトランザクションを定義する情報には直接使われていません。切込み点(pointcut)の定義を介して、関連付けられます。Serviceクラス及びService beanの定義そのものはAOP方式と同じです。

⑦DataSource beanの定義です。Serviceクラス及びService beanの定義そのものはAOP方式と同じです。

 

例題を動かすために①~⑦以外にbeanを定義していますがAOP方式の場合と同じです。

 

AOP方式との違いをまとめると、①②③⑤です。①②③がproxy設定方式のproxy設定に相当します。

 

アプリケーションコンテキストに定義されたAdvisorの情報から、Targetのproxyが構築できることが分かります。図2.1-1と同じようにproxyが自動で作成されることが推測できます。

 

 

3.例題1

3.1 概要

これは、「解説:Springを使う」の例題4を母体にして、トランザクション処理の部分を見えやすくしたものです。トランザクション処理をproxy設定法を使って指定します。

 

トランザクション処理を含まないクラス構成を図3.1-1に示します。

 

図3.1-1 例題のクラス構成(p6)

図3.1-1 例題のクラス構成

 

<<bean>>はSpringのbeanとして定義されます。各beanのidは、Serviceを除いてクラス名と同じで、先頭1文字を小文字にしたものです。Serviceのbean名はserviceTargetとします。図3.1-1に含まれないproxy beanのidをserviceProxyとします。

トランザクション処理はService以降を対象にします。

テストの核になるServiceとDaoについて簡単に説明します。

Daoは次のメソッドを持っています。

(1)public List findAllRecords();

    テーブルの全データを読み出し、各行をList型の1要素として戻します。

    今回のテストには使っていません。

(2)public void addRecord(Dto dto);

    テーブルに1行追加します。dtoを追加する内容を保持しています。テーブルの各列に対応するプロパティをもつJava beanです。

 

Serviceは次のメソッドを持っています。

(1)public List findAllRecords();

    Daoを使ってテーブルの全データを読み出し、各行をList型の1要素として戻します。

    今回のテストには使っていません。

(2)public void addRecord(Dto dto);

    Daoを使ってテーブルに1行追加します。dtoを追加する内容を保持しています。テーブルの各列に対応するプロパティをもつJava beanです。

    今回のテストには使っていません。

(3)public void addRecordToError();

    Daoを使って2行のデータを追加します。

    1行目は正しいデータを追加しようとします。正常に追加されるはずです。

    2行目は型が数値の列に文字列を設定したデータを追加しようとします。DBMSでエラーが検出されます。それが例外としてServiceに伝えられ、1行目も含めてロールバックされます。結果としてデータは1行も追加されません。

 

3.2 データ

DBのデータは一つのテーブルからなります。内容は資料1から入手したものを使わせていただきます。抜粋した内容を表3.2-1に示します。

 

表3.2-1 テストデータ

都道府県 1995年 2000年 2005年 人口性比 人口密度
北 海 道 5,692 5,683 5,627 90.6 72
青  森 1,482 1,476 1,437 89.6 150
岩  手 1,420 1,416 1,385 92 91
... ... ... ... ... ...
沖  縄 1,995 2,000 2,005 100 200

 

テストはデータの内容に依存しません。

 

3.2 指定法

2章の説明はこの例題をベースにしています。実際のソースと2章の説明を参照下さい。

 

4.例題2

4.1概要

内容は例題1と同じです。トランザクション処理をAOP方式を使って指定します。

指定法はトランザクション処理の指定を

例題1実際のソースと2章の説明を参照下さい。

 

 

 

5.資料

(1)'http://www.stat.go.jp/data/nihon/zuhyou/n0200200.xls

都道府県別人口と人口増加率

 

以上