- - PR -
OracleConnectionのDisposeについて
1
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2009-04-15 00:25
いつも参考にさせていただいております。
Visual Studio 2005 C# ASP.NET Oracle10g 現在、イントラ内のWebアプリ開発および保守をおこなっており、DB接続にはSystem.Data.OracleClientを使用しています。 実際には、プロパティとしてSQL、Parameterを渡しDataSetを返すメソッドをもつ ラッパークラスを作成してDBとのやりとりをおこなっています。 (メソッド内でOracleConnection,OracleCommandをusingを使用して インスタンス生成しています) 先日までは何の疑問もなくこのラッパークラスを使用していたのですが、 このほど別会社からの納品物を修正することになり、そこに定義されていた DBアクセス用のラッパークラスを確認したところ下記のような作りになっていました。 OracleConnection、OracleCommandはメンバ変数として定義 コンストラクタ : OracleConnection、OracleCommandのインスタンス生成 DataSetを返すメソッド : 生成したインスタンスを使用して処理 自前のCloseメソッド : OracleConnectionのClose,Dispose OracleCommandのDispose この内容だと自前のCloseメソッドの呼び忘れや処理中の例外でConnectionのClose、 Disposeがおこなわれないのではないかと思い納品元に問い合わせたところ、 ・連続してSQLを実行するときにいちいち接続しなくていい ・規約として必ずCloseを書けばいい といったような回答が来ましたが、いまいち釈然としません。 せめてこのクラスにiDisposableが定義されていれば使用する側で usingを使用してインスタンス生成すればいいような気もするのですが・・・。 一般的にDBアクセス用のラッパークラスを作成するとしたら、Connection等の Disposeはどのようにおこなうものなのでしょうか?漠然とした質問で申し訳 ないのですが、どなたか「自分はこうしているよ」等のアドバイスを頂けたら 幸いです。 | ||||||||||||
|
投稿日時: 2009-04-15 07:37
dispose については、過去にも何度も話し合われています。 基本的に、ファイナライザーがオーバーロードされて、ファイナライザーで破棄されていれば大丈夫です。 規約は絶対に守られる訳ではないので、守られなかった時にも安全であることを出来るだけ保証するよう、クラス ライブラリを作成します。その辺は、MSDN ライブラリに書かれています。 連続して云々について、もう少し突っ込んで聞いてみて下さい。再接続の時間が省けるという理由であれば、「接続プールが使われるので時間はかからない」と指摘してみて下さい(事前に調べておいて下さい)。また、「閉じずに再度開こうとしたら、どうなりますか?」とも。こういったテストは、開発元でされているべきですが、問い合わせ前に軽く試してみて、望ましい結果になるか、確認しておくのもいいでしょう。 | ||||||||||||
|
投稿日時: 2009-04-15 22:59
Jittaさん、回答ありがとうございます。
申し訳ありませんが1点教えてください。
とはラッパークラスに~(クラス名)を実装し、最終的にそこで必ず破棄すれば大丈夫、ということでしょうか?
こちらについては明日、接続プールについての指摘をしてみるつもりです。 接続プールの存在自体については知っていたのですが、接続の再利用?といった 漠然とした知識しかなかったため、今回を機にしっかり調べてみたいと思います。 ちなみに、「閉じずに再度開こうとしたら」についてはクラス内では何も意識され ていませんでした。こちらで試したところ例外が発生していました。 テスト段階で潰せる話ではありますが、これは"ナシ"だと思いますので、含めて 指摘してみたいと思います。 | ||||||||||||
|
投稿日時: 2009-04-16 00:39
なんとなくおかしな方向にいってしまってる気がするんですが…
Jittaさんがどのような意図で書かれたのか分かりませんが、少なくともここでの話題ではファイナライザで大丈夫というのはちょっと方向が違うでしょう。 普通にIDisposableを実装するのが親切であり適切だと思いますよ。 で、普通に考えれば、このクラスにファイナライザをさらに実装するのは間違いです。
どういう意味でナシでしょう? 普通にありで、むしろ適切な動作ではないかと思いますが… あとはまあ、トランザクションの管理がどうなっているか、などが気にするべき点かなと思います。 接続を開いたままにするのはどちらかというとトランザクションの管理で意味があることの方が多いと思いますので。 | ||||||||||||
|
投稿日時: 2009-04-16 07:35
close(dispose)を書き忘れた場合…あ、中で使ってる dbconnection のファイナライザーで dispose されますね。
不要でした。ご指摘ありがとうございます。 | ||||||||||||
|
投稿日時: 2009-04-19 19:51
なちゃさん、ありがとうございます。
なかなか時間がとれず返事が遅くなってしまいました。
例外を発生させないため、一度接続をきって再接続、もしくは接続前にチェックして エラーを返す、と考えていたのですがたしかに一度接続を切って、はトランザクション 管理としておかしいですし、エラー出力はそもそもプログラムレベルの誤りで出して そまってもユーザはどうにもできないため、おかしな判断でした。 なちゃさんのおっしゃるように現在の形を適切としました。また、iDisposableについて は開発元に実装、全呼び出し元の修正という形で依頼を出しました。 Jittaさん、なちゃさん、ありがとうございました。 |
1