Java Springの逆引きメモ -4ページ目

Java Springの逆引きメモ

JavaのSpring frameworkのメモを書いていきます!
初心者の勉強ノートなので間違いがあるかもしれませんが、何かヒントになることがあれば幸いです。

Spring Batchを使用できる状態にするにはどのような準備が必要でしょうか?

それを簡単に見ていこうと思いますビックリマーク



【準備】

以下のことする必要があります。

バージョンはこの記事を書くに当たって試してみたものを記述しています。


 1.ライブラリのダウンロード

   Spring Batchを使用するには以下のライブラリをダウンロードしてプロジェクトに入れます。

   このくらいあればだいたい動くと思います。(色々やってみて足りないときは順次追加してください!)

    ・antlr-2.7.5.jar

    ・asm-all-2.2.3.jar

    ・aspectjrt.jar

    ・aspectjweaver.jar

    ・cglib-nodep-2.1_3.jar
    ・commons-beanutils-1.8.0.jar

    ・commons-collections-3.2.1.jar
    ・commons-dbcp-1.2.2.jar

    ・commons-digester-1.8.jar
    ・commons-io-1.1.jar
    ・commons-lang-2.3.jar
    ・commons-logging.jar
    ・commons-pool-1.5.jar
    ・commons-validator-1.3.1.jar
    ・log4j-1.2.16.jar
    ・spring-2.5.6.jar
    ・spring-context-2.5.6.jar
    ・spring-core-2.5.6.jar
    ・spring-test-2.5.6.jar
    ・spring-batch-core-2.1.2.RELEASE.jar
    ・spring-batch-infrastructure-2.1.2.RELEASE.jar
    ・spring-batch-test-2.1.2.RELEASE.jar
    ・xstream-1.3.1.jar
    ・jettison-1.0.1.jar
    ・junit-4.4.jar

    ・hsqldb.jar (2.0.0) ←DBを使用したくない場合や、サンプルを動かしたい場合に使用



 2.DBの作成

   Spring Batchは前回の記事で見ましたように実行結果の保存先が必要でそれはDBになります。

   必要なテーブルを作成しましょう!


   実は、JARファイルの中にcreate table文が入ってます。

   Spring BatchのJARファイルの中をeclipseか、解凍ソフトで解凍して以下のパスを見てみてください。


     org/springframework/batch/core/

             schema-hsqldb.sql

             schema-mysql.sql

             schema-oracle10g.sql

             schema-postgeresql.sql      などなど    


   スキーマは上記のようにいろいろ用意されています!


   ファイルを開いてそれぞれのDBで実行するだけです!



【説明】

簡単な説明を記述しておきます。


1.SpringBatchでは、宣言的トランザクション管理を使用したり、処理結果などをJSON形式で保存したり

 しているようです。

 そのため、xstreamや、cglibなどのライブラリも必要になります。


 ちなみに、hsqldbは純正Java製のDBです。

 ダウンロードしたSpringBatch(2.1.2)を解凍するとサンプルが出てきます。

 その中を検索すると以下のクラスがあります。

   test.jdbc.datasource.DataSourceInitializer


 このクラスはテスト用のクラスで、SpringでDIされたときにafterPropertiesSet()内で、HSQLDB内に

 create tableします。つまり、テスト用に起動のたびに必要なテーブルを作ってくれます。


 <補足>

 ちなみに、テストのためであれば保存先をメモリ上にすることができるクラスもあります。


  org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean

 こういったクラスもうまく使って動作実験してみましょう!




2.スキーマについて

 スキーマについては特に記述することがありません。。

 すみません。

 こちらを参照ください。


  http://static.springsource.org/spring-batch/reference/html/metaDataSchema.html




これで多分、サンプルなども動くかと思います。




参考:

・トップ

・SpringBatch機能について



SpringBatchではExecutionという概念が出てきます。

これが何を表すかを簡単に見ていきたいと思います。


まず、ひとことで。


Executionは、処理の結果や、状態を保持するクラスです。



【用意されているクラス】

SpringBatchで用意されているクラスには以下のものがあります。


 ・JobExectution

    Job全体の結果とStepExecutionを持ちます。

 

 ・StepExecution

    1つのStepにつき1つのStepExecutionを作成します。

    開始の状態と終了時の状態だけを保持します。

    Stepは途中で失敗した場合、自動でリトライすることもできますが、

    このときもStepExecutionは、リトライ毎の状態をすべて持つのではなく、

    1つの終了状態だけを持ちます。

    


  <イメージ>
Java Springの逆引きメモ

 ※idは、JobInstanceの識別子を表しています。

  詳しくは、・SpringBatch機能について を参照。



【誰が生成するのか?】

上記のExecutionはJobなどのSpringBatchの機能が勝手に生成してくれるので

プログラマーが生成に関して特に気にする場面は少ないかと思います。


ちなみに、Executionはリポジトリから取得します。

リポジトリはたいていDBからExecutionの情報を取得します。

(保存先、取得先は使用するリポジトリによって変わります。)

取得先にまだ生成されていなければ生成します。



【Executionの利用のされ方】

では、何に利用するのでしょうか?

SpringBatchにはリトライ機能や、処理結果による条件分岐などの機能があります。

これは処理結果が分からないと処理できない機能です。

実はこのような機能で使用することになります。


例えば、StepExecutionは開始の状態と終了の状態しかもっていません。

Step処理の途中途中の細かな情報は持っていないのです。

しかし、あるStep処理が途中でエラーが発生してしまったとします。

この場合、どこまで終了しているかさえ分かればリトライ処理が実行できます。

つまり、終了の状態さえ知っていれば十分と言うことになります。


条件分岐の機能も終了の状態さえ知っていれば処理できます。


ですので、StepExecutionは、開始と終了の状態しか持っていないようです。




【その他】
上記でIDや状態を保持するのがExecutionだと説明しましたが、もうひとつ記憶しておいた方がよいことがあります。

ExecutionはExcecutionContextを持っています。

ExcecutionContextは、データをリポジトリに保存できるMapです。

リポジトリに保存できると言うことは、実行中はもちろんのこと、バッチ終了後も保持され、参照・更新ができることになります。

SpringBatchが途中でFAILして終了しrestartしたいときにどこまで処理をしているかを保存しておきたい場合や、他のStepで作成した値を使いたい場合などに便利です。


ExcecutionContextはJobExecution、StepExecution毎に1つ持っています。

Step内だけで使用する場合はStepExecution内のExecutionContextを使用し、

Step間をまたぐような値の場合はJobExecution内のExecutionContextを使用しましょう。

上でも書きましたが、JobExecutionは起動のたびに新規作成されます(違うExecutionのIDで)。

つまり、1つのJobInstance(パラメタが同じ起動)に対しても、複数のJobExecutionが存在します。

(同じパラメタでも-restart, -nextで起動できるので何回でも起動できるので)
その点は頭においておき、気をつけましょう。


【参考】

StepExecution クラスのプロパティ

status A BatchStatus object that indicates the status of the execution. While it's running, the status is BatchStatus.STARTED, if it fails, the status is BatchStatus.FAILED, and if it finishes successfully, the status is BatchStatus.COMPLETED
startTime A java.util.Date representing the current system time when the execution was started.
endTime A java.util.Date representing the current system time when the execution finished, regardless of whether or not it was successful.
exitStatus The ExitStatus indicating the result of the execution. It is most important because it contains an exit code that will be returned to the caller. See chapter 5 for more details.
executionContext The 'property bag' containing any user data that needs to be persisted between executions.
readCount The number of items that have been successfully read
writeCount The number of items that have been successfully written
commitCount The number transactions that have been committed for this execution
rollbackCount The number of times the business transaction controlled by the Step has been rolled back.
readSkipCount The number of times read has failed, resulting in a skipped item.
processSkipCount The number of times process has failed, resulting in a skipped item.
filterCount The number of items that have been 'filtered' by the ItemProcessor.
writeSkipCount The number of times write has failed, resulting in a skipped item.



参考:

・SpringBatch機能について

・実際に作成するものとは(Stepの概念について)

・CommandLineJobRunnerとは?

・自作クラスをrestartできるようにするには?

この記事の前に1つ前の記事を読んでみてください。

 ・SpringBatch機能について



ここでは、実際にSpringBatchで処理を作るための概要を見ていきたいと思います!



【プログラマーがやること(概要)】

やることは主に以下のことです。


 ①Stepの中身をプログラムする。

  (StepはSpringにおける処理の単位。1つ前の記事 参照)


 ②SpringのApplicationContextファイルに、処理の仕方(条件分岐、順番、並列かシーケンシャルか)などを

  Step単位で記述する。

 



【①Stepについて(概要)】

Stepはさらに3つの処理を持っています。

Java Springの逆引きメモ
  <3つの処理の説明>

  ItemReader   ・・・データの読み込みを担当するクラス

  ItemProcessor ・・・読み込んだデータの処理を担当するクラス。(例えば日付の書式を変えるなど)

  ItemWriter    ・・・処理したデータをどこかに書き込む処理を担当するクラス。


  <説明>

  上記3つのクラスはinterfaceですので、実装は各interfaceをimplementsして作ります。

  そして、 ①で取得した1つのデータを ⇒ ②で処理し ⇒ ③で書き込む。

  この①~③の操作を①の読み込みでデータがなくなるまで繰り返します。

  これが1つのstepです。

 

  付け加えておくと、3つのクラスはSpringで最初から用意しているクラスもあります。

  例えば、ItemReaderには、CSVファイルからデータを取得するクラスが用意されています。

  これらを使用できるケースであれば、ItemProcessorくらいしか作る必要がなくなります。

  便利ですねにひひ


  


【②処理の記述について (ApplicationContextファイルの作成)】

SpringのApplicationContextにはSpringBatchのためにいくつかのタグが追加されたようです。


以下では正確な記述ではないですが、設定ファイルの書き方の雰囲気を見ていきましょう。

前回の概要の記事 で出てきた登場人物も出てきます。



リポジトリの設定
<job-repository id="jobRepository"
   data-source="dataSource"
   transaction-manager="transactionManager"
   isolation-level-for-create="SERIALIZABLE"
   table-prefix="BATCH_"
/>


JobLauncherの設定
<bean id="jobLauncher"
      class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property ref="jobRepository" name="jobRepository" />
</bean>



トランザクション処理
<aop:config>
   <aop:advisor 
     pointcut="execution(* org.springframework.batch.core..*Repository+.*(..))"
     advice-ref="txAdvice" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
   <tx:attributes>
      <tx:method name="*" />
   </tx:attributes>
</tx:advice>


ジョブの設定 <job id="sampleJob"> <step id="step1"> <tasklet> <chunk reader="itemReader1" writer="itemWriter1" commit-interval="10"/> </tasklet> </step> <step id="step2"> <tasklet> <chunk reader="itemReader2" writer="itemWriter2" commit-interval="10"/> </tasklet> </step> </job>


<簡単な説明>

最初に、

Execution の保存・取得先であるリポジトリの設定をしています。

Executionは、バッチ処理の結果を保持するクラスです。StepExecution、JobExecutionなどがあります。


次に、

トランザクションの設定をしています。

この部分はたいていのSpringバッチの処理では同じ記述になるとのことです。

トランザクションがcommit/rollbackされる単位はチャンク(chunk)と呼ばれる単位です。

チャンクはstepタグの中で設定されます。


最後に、

本命であるJobの処理を設定しています。

Jobは複数のstepを持っています。

そしてstepはItemReader, ItemProcessor, ItemWriterを1つずつ持っています。

ここではItemProcessorは記述していませんが、処理が何もない場合は記述しないこともできます。

chunkについては以下でもう少し説明します。



【Step内のchunkについて】

commit-intervalは、ItemReaderを10回実行する毎にItemWriterが呼ばれ、書き込みとcommitをする、ということを指しています。

つまり、10回を1チャンクとして処理がされます。


 処理イメージは以下のとおりです:

  List items = new Arraylist();
  for(int i = 0; i < commitInterval; i++){

    Object item = itemReader.read();

    item = itemProcessor.process(item);
    items.add(item);
  }
  itemWriter.write(items);

  

  
Java Springの逆引きメモ
      ※read/processは上記では2回しか繰り返してませんが、

      commit-intervalの回数繰り返されます



【プログラムの起動】

では、一生懸命設定し、作成したプログラムを起動してみましょう!

SpringBatchでは、コマンドラインから実行するためのクラスが用意されています。

このクラス内にはmain関数が用意されているため、以下のように使用できます。


> java CommandLineJobRunner applicationContext.xml sampleJob target(date)=2010/01/01


applicationContext.xml内に設定したJobLauncherを利用して、指定したjob名「sampleJob」を実行します。


コマンドライン以外にも、WEBから非同期にJobを実行することもできるようですが

ここでは省略します。



さて、なんとなく全体的な処理とやらないといけないことが分かりましたでしょうか?

もしうまく伝わっていましたらとっても嬉しいですニコニコ




参照:

・トップ

・SpringBatch機能について

・Executionとは? (SpringBatch用語)

Springのバッチの機能の概要を見てみましょう!


一言でいえば、「バッチ処理を扱う機能」です。




【用意されている機能】

Springのバッチ処理には、主に2つの機能があります。


 ・スケジューリング機能

      定期処理を実施する機能。裏ではquartzや、Java's Timerの機能を使用している


 ・バッチ処理機能

      ループ処理、並列処理や、失敗時に処理を変更するなど、処理の動作を定義して実行する


Springプロジェクトの位置づけ上で、2つ共をSpringBatchというカテゴリで括るのが正しいか分かりませんが、ここの記事では括ってしまいました。大丈夫かしら汗


さて、スケジューリングはクーロンのように起動するだけなのでそれ程難しくありません。

実際に使用例の記事 を見てもらうほうがいいかと思います。


ですので、以下では簡単にバッチ処理機能を見ていこうと思います。

もっと詳しい内容はおいおいで記事にできればと思っています。




【バッチ処理機能】

まず、Springが提供するバッチ処理について見ていきましょう。


ちなみに現状では、バージョン1.x と 2.xが提供されています。

1.xは古い上に、作らなければいけないクラスが多いようで、あまり触れたくないので2.xを扱っていくことにします。



<Springバッチの走行の考え方>

言葉をいくつか覚えないといけません

そこで、一番おおまかな概要からではなく、少し細かなところから説明を開始します。

まあ、森を見る前に少し木を見ておこう的な感じかなむっ

Springバッチでは起動を管理するための「JobInstance」という概念があり、理解しておく必要があります。


JobInstanceの簡単な説明:

 JobInstanceは、起動を一意に指定する識別子のようなものです。

 実際に一意のidも振られます。

 例えば、毎日2回、2時と14時に起動するようにクーロンにスケジュールした場合、

 起動を特定したい場合、「2010/8/17の14時のバッチ」と指定すれば1つに特定できると思います。

 これをしているのがJobInstanceです。

 特定さえできれば、「2010/8/17の14時のバッチ」の結果はどうなってるの?とか、

 「2010/8/17の14時のバッチ」を再起動しよう!、とかをJobに命令することで可能になります。


 さて、これだけだと良く分からないと思いますので、以下で具体的に見ていきましょう。



このあとの例題は、主にJobInstanceの概念を確認するためのものです。

運用でバッチを走行するとき、一般的には定期的にクーロンなどでjavaを起動します。

この例題でもクーロンで1日1度起動するように設定したとします。
バッチ処理内容は、「パラメタtargetに日付を指定するとその日のデータの処理をする」というものです。


 起動イメージ:

  > java CommandLineJobRunner launcher-context.xml Job1 target=2010/01/01


   ※実際には、CommandLineJobRunnerの部分はパッケージ名を記述する必要があります。

    見づらくなるので省略しているだけです。

 参考:

   ・CommandLineJobRunnerとは?



<1日目>
Java Springの逆引きメモ

※上の図は、クラスをDBに保存したときの図です。


  <各オブジェクトの説明>

   JobParameter ・・・ 起動時のパラメタを表すクラス

   Job       ・・・ 起動するバッチ処理を定義したクラス

   JobInstance ・・・ Job名とパラメタを保持したクラス。起動した処理を識別するための概念。

               以下の起動(3)も見ないと分かりずらいと思います。

   JobExecution・・・ Jobの状態、結果などを保持するクラス。JobInstanceも保持しています。



  <図の説明>

  2010/01/01 のデータを処理させようとしてバッチを起動。

  しかし、失敗してしまった。

  

  Jobが起動されると、JobInstanceが生成されます。

  さらに、JobInstanceがJobの処理状態や結果などを保持するJobExecutionを作成します。


  


<2日目>


Java Springの逆引きメモ


  <図の説明>

  今度は1日目と違う日付2010/01/02のデータを処理させようとしてバッチを起動。

  うまくいった!


  JobInstanceの生成は1日目と同様に行われますが、1日目とは違うJobInstanceが生成されます。

  1日目とJob1を起動したことは一緒ですが、JobParameterが違うからです。

  JobInstanceは、JobとJobParameterが同じときは同じ処理、と認識します。

  今回は違うのでid=2という新しいidが振られました。




<3日目>
Java Springの逆引きメモ



  <図の説明>
  1日目に失敗したことに気づき、手動で1日目と同じパラメタで再走行をし、成功した。

  起動イメージは以下の感じです。

    > java CommandLineJobRunner launcher-context.xml Job1 -restart


  このとき、JobとJobParameterは1日目と同じになります。

  ですので、id=1という1日目と同じJobInstanceが生成され、1日目と同じ処理だと認識されます

  

  ただし、JobExecutionは新しいものが作られます

  結果は起動ごとに当然ながら違いますので、これは分かりやすいですよね(‐^▽^‐)。



<同時起動>

  さて、次にもう少しJobInstanceについて見識を深めましょう!


  2つのケースを考え、Jobが実行されるかどうかを見ていきます。


  (1)1日目の処理が24時間以上かかり、2日目の処理が起動されてしまった場合

   ⇒2日目の処理は問題なく起動されます。


  (2)1日目の処理が24時間以上かかり、それに気づかずもう一度、1日目と同じ処理を起動してしまった場合

   ⇒JobExecutionAlreadyRunningExceptionが発生し、異常終了します。

  

  基本的にSpringBatchでは、JobParameterが違う場合は違うデータを処理するように設計するようです。

  このルールどおり実装された場合、1日目と2日目ではJobParameterが違うので

  処理する対象データが違い、お互いに影響を受けない処理であることが分かると思います。

  これはJobInstanceが違う場合は同時に実行しても問題ないということと同じです


  SpringBatchは、JobInstanceが違う場合(1)は2重起動OKにしているようです

  つまり、Job名が同じ処理が起動される場合でも、パラメタが違えば起動OKです。


  では(2)の場合はどうでしょうか。

  今度はJobInstanceが同じなので2重起動と認識して

  例外JobExecutionAlreadyRunningExceptionが発生します


  

  なんとなくJobInstanceという概念が分かりましたでしょうか?




<全体の概要>

次に、森を見ていきましょう!

SpringBatch全体の動きです。


Java Springの逆引きメモ

まず、一番偉い人は、JobLauncherというJobの実行者です。

このクラスは、JobParameterとJobを引数に受け取ってJobに実行命令を出します(①②)。

JobLauncherは実際にはinterfaceで、Springがいくつか実体クラスを用意してくれています。

ですので自分でクラスを作るケースはほとんど無いかと思います。


ちなみに実体クラスの例を書くと、SimpleJobLauncherクラスなどがあります。



次に見るのはJobとStepです。

Jobの中には複数のStepが存在し、これが実際の処理になっています

Jobに実行命令が下ると内部のStepを設定どおりに次々に実行していきます。


JobはStep単位で処理を操作することができます


 操作例1: 普通に順番に処理する

   Step1 ⇒ Step2 ⇒ Step3


 操作例2: 条件分岐を入れる

   Step1 ⇒(失敗時) Step2

        ⇒(成功時) Step3


 操作例3: 並行処理

   Step1 ⇒ Step2 ─⇒ Step4

        ⇒ Step3 ┘


 ※なんとなくStepのイメージ付きましたでしょうか?

  


最後に

JobRepositoryですが、これは結果(Execution )の保存先です。

JobLauncher、Job、Stepは、JobRepositoryを通してDBからExecutionを取得したり、保存したりできます。

例えば、Step1が終了するとその結果(StepExecution1)をDBに保存します。

Step2が終了すればその結果(StepExecution2)をDBに保存します。

こうして次々に結果が保存されます。

最後にJob全体の処理結果(JobExecution)がDBに保存されます。
すべての処理が終了し結果が保存されるとバッチ処理が終了します。


これでだいたいの概要の説明は終了です!

なんとなーく分かっていただければうれしいですが、どうでしょうか?


もう少し詳しい内容は、言葉の定義や、他の記事でサンプルを見ながら記述していこうかと思います。
つたない文章をここまで読んでいただきありがとうございました!!


次の記事もSpringBatchの基本概念になりますのであわせて最初に読んでいただけると嬉しいです。

 ・実際に作成するものとは(Stepの概念について)


【注意】

すみません。カテゴリがSpringBatchの記事はまだ実際に動作するプログラムを試していません。

SpringBatch本家のドキュメントを英訳してまとめただけなので、英訳を間違っているかもしれません。

自分の英語力は5段階で1だったので(笑)ご注意ください。すみません。m(_ _ )m

間違いあればコメントなどで教えていただければ修正します。



参照:

・トップ

・SpringBatch機能について

・実際に作成するものとは(Stepの概念について)

・CommandLineJobRunnerとは?

・Executionとは? (SpringBatch用語)

・WEB上で定期的に何か処理をするには?

・Spring Batchを起動するには? (基本編)

・Stepを使って処理を書くには?

・複数のStepをひとまとまりで扱うには?(flow)

・条件分岐をさせるには?

・DBにデータを読み書きするには?

・データの書き込み(コミット)タイミングを制御するには? (restart機能もついでに見る!)

・バッチ処理を非同期で起動するには?

・ItemWriterの出力先をメールにするには?

・自作クラスをrestartできるようにするには?

・ItemReaderで読み込んだデータを妥当性チェックするには? (valang方式)

SpringBatch本家のドキュメント

Spring Batchについて

Spring Batchで簡単にバッチを作る

FootBallを例題にサンプルを作る(英語ですがサンプルだけでも参考になります)


前の記事 で見たプログラムによるトランザクションを見ていきます。


実はSpringが提供するプログラムによるトランザクション管理は、2種類あります。

その2つ目です。

1つ目は、こちら を参照。


サンプルを中心に見ていきます!




【ビジネスロジック】

public interface MemberService{ List<String> find(String name); } //setter/getterは記述を省略しています public class MemberServiceImpl implements MemberService{
private MemberDao memberDao; private DataSourceTransactionManager txManager;

void doSomething(String name){

//プログラムチックなトランザクション管理 DefaultTransactionDefinition txDef = new DefaultTransactionDefinition();
txDef.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT); TransactionStatus txStatus = this.txManager.getTransaction(txDef); try{ this.MemberDao.insert(); this.txManager.commit(txStatus); }catch(Exception e){ this.txManager.rollback(txStatus); } } }




【Spring設定ファイル(AppricationContext.xml)】


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans "

xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"

xmlns:aop ="http://www.springframework.org/schema/aop "
xmlns:tx ="http://www.springframework.org/schema/tx "
xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd ">


<!-- Data Source (例えばPostgres)--> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="org.postgresql.Driver"/> <property name="url" value="jdbc:postgresql://localhost/XXXX" /> <property name="username" value="XXX" /> <property name="password" value="XXX" /> </bean>
<!-- DAO --> <bean id="memberDao" class="dao.MemberDaoImpl"> <property name="dataSource" ref="dataSource" /> </bean> <!-- ビジネス --> <bean id="memberService" class="business.service.MemberServiceImpl"> <property name="transactionTemplateRequired" ref="transactionTemplateRequired" /> <property name="txManager" ref="transactionManager" /> </bean>


<!-- トランザクション管理 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>


<!-- トランザクション処理用クラス。 --> <bean id="transactionTemplateRequired" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager" /> <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED" /> </bean>

</beans>



【説明】


説明がなくても、なんとなく分かるかと思います。

他の宣言的トランザクションやアノテーションによるトランザクションでは、Springの設定ファイルやアノテーション内でトランザクションの方法を設定していました。

しかし、この方法ではプログラムの中でtxDefを使って設定しています。


再掲: txDef.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);


かなりプログラムっぽいですね。

そして、実際のトランザクション自体は、TransactionStatus を使用します。


普通にトランザクションのコードを書いているのと変わらない感じです。

いったい何の得があるのでしょうか?


これは、Springの宣言的トランザクションやアノテーションによるトランザクションと混ぜて使用できます。

例えば、上記のトランザクションの記述を通常のDataSourceを使用するようなやり方をすれば、Springの方法と合わないため、期待した動作が得られないかもしれません



【使いどころ】

この方法の使いどころですが、かなりレアケースかと思います。

ほぼ、他のトランザクション管理の方法でまかなえるので、なるべくそちらを使いましょう


ただ、かなり特化した独自のトランザクションをする場合は使用することになると思います。

プログラムによるトランザクション管理の1個目の方法は、特化しながら同じトランザクションの方法を提供するときにやりやすいと思います。

この方法は、もっと特化したやり方をする場合に使うことになるのかなと思います。




参照:

トップ

・Springのトランザクション機能について

Spring本家ドキュメントでのトランザクションの説明