Top / Hibernate / Springを使ってトランザクション処理を記述する(古い)

Hibernateとトランザクション管理に関する課題

HibernateベースのDAOを作った場合に、トランザクション処理をどのように記述するかが問題になることがあります。

たとえば下記のような二つのテーブル

schema.png

に対してそれぞれMemberDAOとWorkGroupDAOを作ると思います。さらにそのDAOを使用するビジネスメソッド、たとえば

bl.png

なんてのが定義されると思います。

このとき、ある処理の場合はメソッド単位でトランザクション管理し、ほかの処理の場合は複数のメソッドにまたがってトランザクション管理したい場合があります。上の例だと、

  • addMemberはMemberを登録する
  • addGroupはWorkGroup?を登録する
  • addはMemberをGroupに追加する。引数のメンバーがいなかったらaddMemberでMemberを登録する。引数のグループなかったら、例外をThrowする

とした場合、

  • メンバーを登録しようとしてaddMemberを呼び出した場合は、addMember内でトランザクションが開始され、終了すればいい。
  • add内でサブルーチン(<-古っ)としてaddMemberが呼ばれる場合は、addでトランザクションが開始され、終了されるのでaddMemberはすでにあるトランザクションに参加すればよい

となります。一つめの例だとaddMember内でトランザクションの開始・終了の処理を書けばよいですが、二つめの例を考えるとaddMember内でトランザクション開始と終了の処理をしちゃうとまずいわけですね。つまりあるメソッドに対してトランザクションのスコープ(境界?)が場面によって異なることがあるのですが、Springではこの辺をトランザクション処理を宣言的に記述することで解決しています。

この辺を考えるために具体例で行きます。今回考えるクラス群の全体像は以下の通りです。

class.png

またトランザクション処理を考慮しない状態のSpringの設定は以下の通りになっています。

bean.png
bean2.png

Springを使ってトランザクション処理を記述する

さて、SpringではBLのビジネスメソッドに対してトランザクション処理を宣言的に追加することができるといいましたが、以下のようにやります。

まず、BLの名前をuserManagerBLからuserManagerBLTargetに変更し、userManagerBLを新規に作成します。その新たなJavaBeans?の型はSpringが提供してくれるProxyで、外部から見たインタフェースは元のuserManagerBLと同じになります。つまり見た目は外部から見たら全く変わっていないことになります。

そのProxyのタグ付けですが、トランザクション設定や、ターゲットになるJavaBeans?(元のuserManagerBLのこと)の指定などを記述しておきます。

さて処理の流れですが、実際BLを使うプログラムはuserManagerBLというキーでSpringからJavaBeans?を取得するので、処理シーケンスは

BLを使うプログラム -> userManagerBL

だったのが

BLを使うプログラム -> userManagerBL -> userManagerBLTarget

となります。

外部から見たら見た目は同じだけど、実際のBLの間に別のクラスが挟まれる用になります。結局、Springのタグ付けは以下のように変更されました。

after.png

間に挟まれたPOJOは以下のようにSpringでInjectionされています。

<bean id="userManagerBL" 
  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="transactionManager">
    <ref local="transactionManager" />
  </property>
  <property name="target"> ↓ターゲットにするPOJOを指定
     <ref bean="userManagerBLTarget" />
  </property>
  <property name="transactionAttributes">
    <props>   ↓POJOのメソッドに対してトランザクションの設定を記述
      <prop key="*">PROPAGATION_REQUIRED</prop>
    </props>
  </property>
</bean>

この記事は

選択肢 投票
おもしろかった 3  
そうでもない 0  
  • なんか、想定通りにうごかねえなあと思ってたのですが、Linux版のMySQLとWindows版のMySQLのデフォルト値って違うのかな???LinuxのMySQLは、がんばっても勝手にトランザクションが開いちゃうような。。。。Windowsだと、想定通りっぽいんだけだどね -- きの? 2006-07-04 00:32:21 (火)
  • MySQLのトランザクションが開かれたとき、 org.hibernate.transaction.JDBCTransaction - begin がログにでた。 -- きの? 2006-07-05 00:25:08 (水)
  • まとめると、こんな感じ。基本的にMySQLはトランザクションを開かないとInsertとかは反映されない。ただし、Linux版は明示的にトランを開かないとき、誰かが勝手にトランザクションを開始して、勝手にコミットする。Windows版は自分で開く・閉じるをしないと、DBに反映されない。トランザクションが開かれたとき、上のログが出力される。 -- きの? 2006-07-05 00:26:44 (水)
  • 書き途中で、じかんがないっ -- きの? 2006-07-20 22:28:05 (木)

Top / Hibernate / Springを使ってトランザクション処理を記述する(古い)

現在のアクセス:7145


添付ファイル: fileafter.png 496件 [詳細] filebean2.png 430件 [詳細] filebean.png 453件 [詳細] fileclass.png 481件 [詳細] filebl.png 456件 [詳細] fileschema.png 468件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2011-06-13 (月) 08:56:04 (2995d)