session-per-operation antipattern
なるものがあるようです。Hibernate3のマニュアルの「12.1.1. Unit of work」の節に、
First, don't use the session-per-operation antipattern
って形で載ってました。SQL文一個一個に対してセッションを張るなという意味だと思います。
昔、手作りO/Rマッピングしているとき、こんな感じのインタフェース(というかメソッド)を定義してました。
Table1#getTable(String key) : Table1 // Table1がDAOでありDTOでもある Table1#insert() : int // 値はsetterでセット Table1#update() : int // 値はsetterでセット Table1#delete() : int // 値はsetterでセット
データベースコネクションはどこから提供されるかというと、実はこれらのメソッドの内部で逐一取得するということをやってました。今から考えれば、よくぞそんなことをしたものだと思いますが、Jakarta Commons DBCPを使ってプーリングしているためか、これがまあそこそこ動いてしまっています。(まあいいか?)まさに、session-per-operation antipatternですね。
ちなみにこの方式だと、データの一貫性保持とかを考え出した時に、
- コネクション取得
- UPDATE
- コミット
- コネクションクローズ
- コネクション取得
- INSERT
- コミット
- コネクションクローズ
みたいなことになってしまうので、これじゃ出来ないってことになります。
なんだConnectionを引数にして、呼び元でトランザクション管理すればいいんじゃんって、今にしてみれば当たり前のことに行き着いた記憶があります。つまり、
- コネクション取得
- UPDATE
- INSERT
- コミット
- コネクションクローズ
みたいな。
その少し後にJakarta Commons DbUtilsの存在を知って、引数にConnectionやDataSourceを渡すインタフェースがたくさん定義してあって、ああやっぱりと思いましたね。そういえば、今のプロジェクトでも商用縛りがなかったら使ってただろうなぁ。