• ベストアンサー

トランザクション管理について

皆さんはトランザクション管理を何処で行ってますか? 大体のプロジェクトでは以下の2パターンに集約されると思います。 1.ビジネスロジックでトランザクション管理して、DAOへ引数としてトランザクションを渡す。  当然、コミット・ロールバックはビジネスロジック側で管理。 2.ビジネスロジック側では管理せず、DAO側で管理。  ビジネスロジックへは結果のみ返却。 実は今回のプロジェクト、Java初心者(プログラムって何?レベルとC++なら受講したことあるよ!レベル)が9割を占めるチームです。 初心者の方々はビジネスロジックを設計・実装します。 それ以外の部分(DB・SpringFramework等)を私が設計・実装します。 ビジネスロジックの部分の設計も、概要設計レベルしか記述されておらず、トランザクション無視の設計しかありません。 バグにまみれてデスマーチなんてごめんなので、2のパターンでトランザクションからDB周りを設計したいと思っているのですが、リーダー(スキルは不明。経験はあるらしい)が「DAO側でやると上手くいかない場合が多い」と言われ、却下されそうです。 何処がどう上手くいかないのか聞いても、明確に返答は貰えません。 でもなんとか2のパターンでいきたいのですが、上手い説得方法が見つかりません。 なんて言えば納得してくれそうか、皆様のお知恵を拝借したく投稿しました。 足らない部分は補足させていただきます。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

RDBですか。通常のRDB利用のシステムは、ビジネスロジック:テーブル=1:nの前提で書きます。 (Aテーブル、Bテーブルからデータを取得し、さらにUIからのパラメータも含め計算し、Cテーブルに格納する等) ですので、私はトランザクションはあくまでビジネスロジックの単位にして、DAOはDBとビジネスロジックの仲介役ぐらいに留めておいた方が無難な気がします。 仮にDAO側でトランザクションを管理するためには、DAO自体の粒度が1トランザクションとなるため、 発生しうるトランザクションを全て考慮しないと整合性のとれたI/Fを持ったDAOが設計できないって事ですよね? 概要設計が出来た箇所から実装しなければいけない今回のPJではことさら難易度が高いのでは? 出来ている部分からDAOを作って、後続の要求に対応するために、ぐちゃぐちゃのI/Fあるいは膨大の数になってしまったDAOの面倒をみなければいけない、なんて辛すぎます。 なので、私は1.の方がいいです。 ビジネスロジックが呼ばれた時点がトランザクションの開始、ビジネスロジックが終了する時点がトランザクションの終わり、 といった形のトランザクションのフレームワークを作って、commit、rollbackを受け持っちゃた方がすっきりしませんか? 長々と書いてしまいましたが、そもそも私のイメージしているシステムと違ったら私の意見は無視してください。相当困難なPJと見受けられますが成功をお祈りしています。

A_Bone
質問者

お礼

ご回答ありがとうございます。 今回DAO側ではSelectに関してはQueryItratorパターン、それ以外に関してはPersisterパターンを参考に実装する予定です。 コネクションはコネクションプーリングを実装する予定です。 Persisterについては複数テーブルに複数操作(Insert/Update/Delete/複数ワザ(Insertで一意制約違反ならUpdateとか))する場合、その途中でExceptionが発生した場合、全てをロールバックする必要もあると考え、単純にPersisterパターンを実装するのではなく、executeUpdateを実行する前にValueObjectと操作内容のMapが(ビジネスロジック側で)設定されたArrayListを解析しながら実行しようと考えています。 つまり1ArrayList1トランザクションといったイメージです。 そうするとビジネスロジック側はDAOのArrayListに値を設定し、最後に全部の操作を一括して行うメソッドを呼び出すだけで、トランザクションのことを気にせずに実装できます。(2のパターンを利用した場合) しかし1のパターンで行った場合、ビジネスロジック側で途中でロールバックをかけるとか、そういうことが果たして(トランザクション/try~catchを知らない初心者に)できるのか?と思わざるを得ません。 Selectに関しては、for updateの時以外は1Select1トランザクションと考えています。 具体的なメソッドとしては検索キーだけを引数に渡すquery(key:Map):Listとトランザクションも引数にしているquery(key:Map, tran:Transaction):Listのパターンを実装予定です。(リーダーは後者のみで良いという事で、トランザクションの管理意識の違いが浮き上がってきた状況です。) > 相当困難なPJと見受けられますが成功をお祈りしています。 ありがとうございます。外注はあくまでも害虫?って状況なので、適当に逃げる手段を作っておかなきゃいけないかもしれませんね。 ともかく、ナントカがんばりたいと思います。

A_Bone
質問者

補足

ここまで書いていて思ったのですが、いっそのことDAOにトランザクションを設定させるsetTransaction(tran:Transaction):voidを作り、実行メソッド呼ばれた時に、クラス変数になけりゃトランザクション作る形ではどうかなと思い始めてますが、プロの目から見ていかがでしょう? 結果として自由度を上げる形になり保守が面倒くさくなると思いますが、初心者の方々が結局どっちを使うかは、コレで明白になると思います。(多分setTransactionは使われないでしょう。トランザクションって何?って言う人達だし。) ビジネスロジックでトランザクション作っても、別でトランザクション作るので、なんだかおかしい感じにはなると思うものの、何よりここでバグが出なくなると思うのですが…ダメですかね?やっぱり^^;

その他の回答 (3)

回答No.3

参考URLの内容によると、DAO[Data Access Object]パターンを使わない場合(質問者さんの言う1.の方)、「データアクセスの手段や実装が変わると、ビジネスロジック中からデータアクセスをしている個所を見つけだし、変更していかなければなりません。」とあります。 個人的には、パターンさえ使えばいい、という考えには少し疑問がありますが、分析・設計の部分がしっかりしていさえすれば、開発者さん達もちゃんと後からついてくるとは思いますが…。

参考URL:
http://www.nulab.co.jp/designPatterns/designPatterns3/designPatterns3-4.html
A_Bone
質問者

お礼

参照URLありがとうございます。拝見いたしました。 なるほど、保守性が下がることを説得材料のひとつとしていけばいいかもしれない ということですね。 納品したら保守なんてやらん って言っているんですが^^; ビジネスロジックは、#1様の補足にも記述させていただきましたが、私は殆どノータッチになります。 リーダーがどうしても1のパターンでやると推し進めるのであれば、デスマーチに入る前にプロジェクト離脱も考えていたりいなかったり^^; あとは、ビジネスロジックの基底クラスを設けて、そこでトランザクション管理をして、それを継承する形でビジネスコンクリートクラス というスタイルも考えていますが、そこまでするんなら、DAOでやっても一緒やん なんて思ってしまいます。 > 分析・設計の部分がしっかりしていさえすれば、開発者さん達もちゃんと後からついてくるとは思いますが…。 そうなんですよね。 でも、そこの部分を書いている人達が「try~catch?」「トランザクション?コミット?何それ?」って言う状態じゃ… ん~~~何でこんなに頑ななんだろう? やっぱり外注の言う事なんて聞きたくない って事なんでしょうか?(涙 ご回答ありがとうございました。

回答No.2

DBはRDB?OODB?XMLDB?どれで考えられてますか?

A_Bone
質問者

補足

DBはRDB、Oracle10gR2を使用予定です。 アドバイスよろしくお願いします。

noname#30871
noname#30871
回答No.1

 あなたは、1のパターンの何処がどう上手くいかないとお考えですか。なぜ、1だとバグにまみれてデスマーチになるのですか。

A_Bone
質問者

補足

補足要求ありがとうございます。 まず、質問にも書きましたが、ビジネスロジックを記述している内容にはトランザクションに関するところが見受けられません。 記述している人に「トランザクション関連はどのように処理される予定ですか?」と聞いたところ「トランザクションって何ですか?」と… 他の人にも聞いてみたのですが、異口同音に「トランザクションって何ですか?コミットって?」という返答でした。 一人、COBOLをやっていた人がいて、その人はコミット・ロールバックが理解できていたようですが、実装するのにどのように取り込めばいいのかも分からない状況のようです。 この状態でまともにビジネスロジックでトランザクション管理が出来るとは思えず、そのまま実装した場合、その箇所でバグが出ることは容易に想像が付きました。 勿論、Java経験2~3年ぐらいのメンバーであれば、当然1のパターンのほうがDB周りを作る負荷は減るので大歓迎なのですが、今回はトランザクション分からない人達にトランザクションについて書けというのは、酷なのではないかと思っています。 そのため、1の方法ではなく2の方法が良いと考えたのです。 また、ビジネスロジックの部分も概要設計レベルの内容で実装するということで、正直、トランザクション管理に関してまで意識がまわらないのではないかとも思ってます。(try~catch も知らない人達なので…) 開発手法も、テストファーストは却下され、とりあえず概要設計が出来上がったところから作って行き、最終的にその中から無作為に数本取り出してテストをするということです。 なので、設計の時点で極力バグが出そうなところを排除しないと、納品間際に受け入れテスト(ここは客が全箇所テスト)でバグにまみれてデスマーチになるんじゃないかと危惧しています。 また、ビジネスロジックの設計書はおよそ60本になり、それらに全てトランザクション管理の記述を入れるのは工数的にも時間がないのが正直なところです。 補足になってないかもしれませんが、アドバイスよろしくお願いします。

関連するQ&A