Editionをインストールする。†HibernateベースのDAOを作った場合に、トランザクション処理をどのように記述するかが問題になることがあります。下記のような二つのテーブルに対してそれぞれMemberDAOとWorkGroupDAOを作ると思います。そのDAOを使用するビジネスメソッド、たとえばなんてのが定義されると思います。このとき、ある処理の場合はメソッド単位でトランザクション管理し、ほかの処理の場合は複数のメソッドにまたがってトランザクション管理したい場合があります。上の例だと、addMemberはMemberを登録するaddGroupはWorkGroup?を登録するaddはMemberをGroupに追加する。引数のメンバーがいなかったらaddMemberでMemberを登録する。引数のグループなかったら、例外をThrowするとした場合、メンバーを登録しようとしてaddMemberを呼び出した場合は、addMember内でトランザクションが開始され、終了すればいい。add内でサブルーチン(<-古っ)としてaddMemberが呼ばれる場合は、addでトランザクションが開始され、終了されるのでaddMemberはすでにあるトランザクションに参加すればよいとなります。一つめの例だとaddMember内でトランザクションの開始・終了の処理を書けばよいですが、二つめの例を考えるとaddMember内でトランザクション開始と終了の処理をしちゃうとまずいわけですね。あるメソッドに対してトランザクションのスコープ(境界?)が場面によって異なることがあるのですが、Springではこの辺をトランザクション処理を宣言的に記述することで解決しています。†この辺を考えるために具体例で行きます。今回考えるクラス群の全体像は以下の通りです。例を単純にするために、一つのテーブルに対するトランザクション管理を考えます。UserBL->UserDao->データベースという構成になっていて、UserBLのトランザクション指定をどうやるか、ということですね。対応するテーブルは以下の通り作成しました。(USERID));確認してみます。Productionに接続されました。VARCHAR2(1000)SQL>OKです。ちなみにこの辺のユーザは以下のように作ってます。Productionに接続されました。6ユーザーが作成されました。MKINO_ROLE;ロールが作成されました。12権限付与が成功しました。SQL>権限付与が成功しました。Productionとの接続が切断されました。†さて、SpringではBLのビジネスメソッドに対してトランザクション処理を宣言的に追加することができるといいましたが、以下のようにやります。もとのBLの名前をuserBLからuserBLTargetに変更し、userBLという名前のBean設定を新規に作成します。その新たなJavaBeans?の型はSpringが提供してくれるProxyクラスで、外部から見たインタフェースは元のuserBLと同じになります。見た目は外部から見たら全く変わっていないことになります。そのProxyのタグ付けですが、トランザクション設定や、ターゲットになるJavaBeans?(元のuserBLのこと)の指定などを記述しておきます。userBLTargetとなります。外部から見たら見た目は同じだけど、実際のBLの間に別のクラス(上のProxyクラスですね)が挟まれる用になります。結局、Springのタグ付けは以下のように変更されました。間に挟まれたPOJOは以下のようにSpringでInjectionされています。†さて使用する側から見えるPOJOですが、もともとはUserBLクラスだったのですが今は間にorg.springframework.transaction.interceptor.TransactionProxyFactoryBeanが挟まれている形となっています。このクラスを経由することでターゲットとなるUserBLクラスの各メソッドにトランザクションの指定を書くことができるというワケです。</property>となっていて、全てのメソッドをPROPAGATION_REQUIREDにする、という指定になっています。PROPAGATION_REQUIREDは、このBLのメソッドが呼ばれたときに、すでにトランザクションが開始されていたらそのトランザクションに参加する、開始されてなかったらトランザクションを開始する、という意味になります。このメソッドが呼ばれたときにトランザクションが開始されてなかったら、BLのメソッドのはじめでトランザクションが開始され、全ての処理が問題なく終わったら勝手にコミットする、ということをSpringがやってくれるわけです。これ、すごいことですね。Spring経由でBLを取得し、BLのcreateメソッドでデータベースにデータをInsertしています。PKを生成したいだけ。Sessionなんのこっちゃって感じですけど、BLのメソッドが開始される際にトランザクションが開かれ、メソッドが終わった後にコミットが行われているのがわかると思います。ついでにHibernateのSessionとかも同じタイミングで開いたり閉じたりするんですね。次にメソッド内でわざとRuntime例外をスローした場合のログです。SessionSpringが正しくロールバックしてくれています。自分たちでやる必要はないわけです。ちなみにSpringではRuntime例外はロールバック、その他の普通の例外はコミット、というのがデフォルトの動きみたいです。先のメソッド指定で、普通の例外もロールバックみたいに挙動を変えることもできます。先のPROPAGATION_REQUIREDはあったらトランザクションに参加、なかったらトランザクションを開始する、でしたが他にも色々指定があります。PROPAGATION_MANDATORYでしょうか。これは、すでに開始されてなかったら例外、というものです。DAOとかをあやまってトランザクション開始しないまま呼び出したりしないようにする場合などに使えるかな。</property>を追加してやってみます。foundという例外がスローされました。</property>などとしてトランザクション指定をしなかった場合はどうなるのでしょうか。実行結果配下の通りです。end当たり前ですが、トランザクションが開始されないで処理がなされてます。Hibernateのセッションは開いて閉じてをちゃんとやってくれてますね。