- ベストアンサー
DBのコネクションのclose処理で例外が発生した場合
- DBのコネクションのclose処理で例外が発生した場合、適切な処理を行う必要があります。
- close処理で例外が発生するのは稀なケースですが、万が一発生した場合にはログ出力や例外のスローなどの対応が必要です。
- 例外が発生した場合、ただ無視することは避けるべきであり、適切なエラーハンドリングが行われるべきです。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
通るすがるです。 >>この場合、おそらくcommitに問題がある可能性大ですね。 >>commitのエラーにより、closeが例外を引き起こすような感じだと思います。 >>片方だけの情報だと、私の見解としては推測が難しくなると思いますけど。 >そうですね。commitもですが、ハードや環境の問題でどっちも失敗するのかなと >思ったりします。ですので、基本的には例外をネストしてしまってもいい気はす >るのですが、それぞれ別の原因だった場合、解析時に混乱しそうな気もしたりし >ています。 たしかに、混乱はします。 ただ、エラー解析ってその場合、一つずつ問題を解決しそれをクリアしたら次の 問題を解決していくと思いますが、大多数のエラー解析時にはそのエラーのストー リー性を組み立てて(仮説)から修正したほうがより早く問題解決につながると 思います。仮に、エラー内容を束ねてしまった場合、その問題を解決し試験した 場合には、さらに別のエラーが発生してまた一から調査を開始することになり 非常に労力を要する結末を迎えることとなると思います。 >ただこのあたりのエラーがclose処理で出る時点で、commitも失敗するのではな >いかと思ってしまったりも・・・。もちろんcommit処理とclose処理の間のピン >ポイントで壊れたということは考えられますけれども。 >とここまで書きましたが、commitは成功したけど、そのあとデータが壊れました >ということですね。確かにその場合はユーザにメッセージを出す必要があります >ね。ただ例外処理が煩雑になるようなところが気になります。 そのとおりです。 ただ、煩雑になるかどうかはあなたの実力次第です。 SEとしての腕の見せ所です。 >発生した例外をすべて内包するようにした場合、発生した例外を変数に保持して、 >close処理で例外が発生した場合、保持した変数をチェックして例外をネストし >たりしなかったり。その方針だとcommit以外にもRuntime系の例外とかもcatchし >なければいけなくなりそうな・・・。 ここの気持ちは良くわかります。ただほかのオブジェクトとしての関係をこのレベル で関連づけてしまった場合、それはもうオブジェクトではなく構造化設計したものと 思います。そうなるとオブジェクト指向としての柔軟性に掛けてしまい結局この部品 は、他システムにおいて使用できないものと思います。 >いけない悪い癖で無用に範囲を広げている気がします。もっとシンプルに考えた >いのですが、どうもてんぱってくるとどうにも。 >頭を整理しなければ・・・。 そうですね、多分ここはロジックベースの指向になってしまって、つまり全ての処理 が2次元(平面的)になってしまい煩雑になってしまう要因とも言えますね。このよう な場合は設計方針を思い出し、つまり取り込み中のクラスは大前提として何をさせる クラスだったのかを思い出しながら整理しては如何でしょうか? 上の回答と同じようになってしまいましたが。
その他の回答 (4)
- ToOrisugaru
- ベストアンサー率28% (80/280)
通りすがるです。 >この辺りまさに当初の疑問であり悩ましいところです。 >ただcommitがうまく完了してclose処理で例外が発生した場合に例外をスローす >るような形になると、commitとcloseの両方で例外が発生した場合に困ってしま >います。どちらかを握りつぶしてしまうか、別々の理由かもしれない例外をひと >つの例外にまとめることになってしまうのではないかと考えています。 この場合、おそらくcommitに問題がある可能性大ですね。 commitのエラーにより、closeが例外を引き起こすような感じだと思います。 片方だけの情報だと、私の見解としては推測が難しくなると思いますけど。 >closeのみで例外が発生した場合、システム的な後処理は失敗しているけれど、 >ユーザの処理自体はうまくいっていると考えました。そう考えるとユーザから問 >い合わせをさせるような形でよいのだろうかと迷いました。 >またユーザからの問い合わせ以外にも、ログを監視してエラーにあたるログを確 >認したらシステム管理者に連絡が来るイメージを考えていました。ユーザは知ら >なくてもいいけど、必要があれば調査するみたいな形でしょうか。 この辺は、ちょっと私がいままで作成したシステムとイメージがちがいますね こうすれば最善というわけでなく、あくまでも例としてご参考に! ログに出力するものってたとえば、こんな内容だと思うのですよ。 下記内容をみると、ユーザー処理自体はうまくいってると考えられますか? 何か対策が必要と思うのですが.. 例として 57P02 クラッシュによる停止 -->システム再起動 58クラス システムエラー -->システム再起動 58030 入出力エラー -->システム再起動 診断チェック F0クラス 設定ファイルエラー -->設定ファイル見直し->システム再起動 F0000 設定ファイルエラー -->設定ファイル見直し->システム再起動 F0001 ロックファイルの存在 -->設定ファイル見直し->システム再起動 Class XX 内部エラー -->方式検討 代替え案検討など XX000 内部エラー -->方式検討 代替え案検討など XX001 データの破損 --> 復旧作業 XX002 インデックスの破損 -->bldindex 53クラス リソース不足 -->ディスクチェック、メモリ使用量調査、 設定ファイル見直し->システム再起動 もしくは、システム再起動 53000 リソース不足 同上 53100 ディスク空き容量不足 同上 53200 メモリ不足 同上 53300 接続過多 設定ファイル調査 この内容を見てエンドユーザーさんが、SEに連絡してくれると思いますか? 多分、無視されると思います。(なんかでてるわ~)みたいな感じで でもSEからしてみれば、障害が発生したときでないと、採取できないと思います。 (ログですから、ある程度たまったら削除とかしますよね? もしくはサイクリック的にログファイル自体を使いまわし、長く運用しても ディスクを圧迫しないような作りにするとか) よって、このようなエラーの場合には ログには上記のような内容をはいて、画面には、以下のような内容を表示させる 形式になると思います。 「システムに重大な障害が発生しました。ログを採取し担当SEへ連絡をお願い します。」 エンドユーザーに専用の運用グループがある場合には、上記コードを参照に 復旧操作マニュアルを参照して対処してもらうという手もありますけど。
お礼
詳細なアドバイスを頂けて助かります。有難うございます。 >この場合、おそらくcommitに問題がある可能性大ですね。 >commitのエラーにより、closeが例外を引き起こすような感じだと思います。 >片方だけの情報だと、私の見解としては推測が難しくなると思いますけど。 そうですね。commitもですが、ハードや環境の問題でどっちも失敗するのかなと思ったりします。ですので、基本的には例外をネストしてしまってもいい気はするのですが、 それぞれ別の原因だった場合、解析時に混乱しそうな気もしたりしています。 両方の例外を含めてスローした方がよいと思われますか? >下記内容をみると、ユーザー処理自体はうまくいってると考えられますか? >何か対策が必要と思うのですが.. 確かにこういったエラー自体を見るとうまくいっているか?という疑問はあります。 ただこのあたりのエラーがclose処理で出る時点で、commitも失敗するのではないかと思ってしまったりも・・・。もちろんcommit処理とclose処理の間のピンポイントで壊れたということは考えられますけれども。 とここまで書きましたが、commitは成功したけど、そのあとデータが壊れましたということですね。確かにその場合はユーザにメッセージを出す必要がありますね。ただ例外処理が煩雑になるようなところが気になります。 発生した例外をすべて内包するようにした場合、発生した例外を変数に保持して、close処理で例外が発生した場合、保持した変数をチェックして例外をネストしたりしなかったり。その方針だとcommit以外にもRuntime系の例外とかもcatchしなければいけなくなりそうな・・・。 いけない悪い癖で無用に範囲を広げている気がします。もっとシンプルに考えたいのですが、どうもてんぱってくるとどうにも。 頭を整理しなければ・・・。
- ToOrisugaru
- ベストアンサー率28% (80/280)
先ほどの続き >通るすがるさんの経験ではどのようなポリシーがあったか、よろしければ >教えて頂けないでしょうか。ここら辺のポリシーを決めないといけない場 >合、自分だったらどうするべきかと悩んでいます。今の時点では2のケース >はほぼ有り得ないとし、close処理で例外が発生した場合はログ出力に留め >るのがよいのだろうかと考えています。が、自分でもしっくりきませんの >で、説明する相手がいたらその人もしっくりこないでしょう。 >どこかで折り合いをつけないといけないのだとは思いますが、その折り合い >をつける際の観点がぴんときていないのでしょうか。 こんなことも考えられます。 一般に、sqlコードというのはエンドユーザーが見る限り非常に分かりずら いものと思います。よってコードによりmsgbox用とログ出力用に振り分け 画面に出力する用とログに吐き出す用で分けるかと思います。 このとき、ログのみ出力するもの、画面のみ出力するものまたはその両方に 出力する場合があると思います。 これは、設計時の共通仕様(?)で振り分けるかと思います。 このような塊がシステムポリシとなってくると思います。 でわたとえば、上記文言で >、close処理で例外が発生した場合はログ出力に留め >るのがよいのだろうかと考えています。 とありますが本当に、これでよいのでしょうか? closeにて環境的なエラー(資源不足関連もしくハードエラー関連のエラー を検出した場合にはどうでしょうか? ログだけ出力してればよろしいのでしょうか? ユーザーがなんらかの障害を検出してSEに調査依頼するような流れのほうが 良くはないでしょうか? 後で解るよりも、その直後に調査したほうが障害復旧のための多くの情報が 残っていると思います。 システムの作り、および例外の検出箇所とsqlコードによる対処それぞれの 組み合わせでどのうようにするのがベストかを検討し、最もふさわしい形にま とめたものも、システムポリシの一部と思います。
お礼
お返事有難うございます。 >とありますが本当に、これでよいのでしょうか? > closeにて環境的なエラー(資源不足関連もしくハードエラー関連のエラー >を検出した場合にはどうでしょうか? この辺りまさに当初の疑問であり悩ましいところです。 ただcommitがうまく完了してclose処理で例外が発生した場合に例外をスローするような形になると、commitとcloseの両方で例外が発生した場合に困ってしまいます。どちらかを握りつぶしてしまうか、別々の理由かもしれない例外をひとつの例外にまとめることになってしまうのではないかと考えています。 closeのみで例外が発生した場合、システム的な後処理は失敗しているけれど、ユーザの処理自体はうまくいっていると考えました。そう考えるとユーザから問い合わせをさせるような形でよいのだろうかと迷いました。 またユーザからの問い合わせ以外にも、ログを監視してエラーにあたるログを確認したらシステム管理者に連絡が来るイメージを考えていました。ユーザは知らなくてもいいけど、必要があれば調査するみたいな形でしょうか。
- ToOrisugaru
- ベストアンサー率28% (80/280)
通りすがるです。 >>close前に更新しようとしてcommitしないでcloseしようとしたが、 >>closeにて例外を検出した場合 > こちらはプログラムのバグということでよろしいでしょうか? > close前にcommit または rollbackしない実装はないと思うので >こちらは想定していませんでした。 プログラムのバグの可能性もありますが環境のバグの可能性も ありますね。dbによって、自動コミットというのがあって 更新系のdmlを発行すると自動でcommitする場合もあります。 ただ、この場合、エラーにはならないと思います。 また、上記の例は、commitでは正常に動作した場合を言ってます。 どちらかというと、ハードまたは環境的な例外検出を想定してます。 >commitしてcloseしようとしたがcloseにて例外を検出した >質問のケースはこちらになります。 >ただrollbackのケースもあるかと思います。 rollbackが完了してcloseした場合の復旧対処って特にないと思い ます。rollbackが失敗した場合には、そこで検出し理由が特定され ますので特に記述しませんでした。 >前回書いた例ですが、例外が発生する場所として3つを考えています。 >1.SQL実行 または commit または rollback時に例外発生 >2.close時に例外発生 >3.上記1,2の両方で例外発生 >finallyのcloseの例外処理でスローしてしまうと、3のケースで1の例 >外発生が隠蔽されてしまいます。逆に例外処理でスローしないと、2 >のケースが例外が発生しているにも関わらずスローされないので問題 >があります。かといって1の例外の中に2の例外を入れ子にするのはど >うかと考えています。例えるならひとつのメソッドから2つの別々のエ >ラーを同時に返却するメソッドになっているようなもので何かおかし >いと・・・。 例外を検出するのはできる限り検出する方向で検討したほうがよいと 思います。具体的には、db接続、dml発行、db切断、コミット ロールバックそれぞれを、try ceach で記述するように。 finallyは書きません。 で例外を検出した場合に、sqlコードが帰ってくるはずなのでそれが 解るように。 >その辺りをシステムのポリシーによると仰っているのかなと思いますが >、一般的にどのようにするのかがピンときません。今までのプロジェク >トでどうだったかというと、正直な話をいえばclose処理で「エラーにな >るようなケースはない」という考えに思えます。close処理でのスローは >行っているところは記憶にある限りありませんでした。close処理でエラ >ーになる以前にSQL発行で失敗するだろう、というポリシーだったのかも >しれません。 たとえば、画面系のシステムがメインでメインメニューとそれから派生 するサブシステムがあり、サブシステムでそれぞれdmlを発行し更新 追加など行うと過程します。 上記システムの場合以下のような使い方があると思います。 1.メインメニューで接続、切り離しを行い、それぞれのサブ機能でsql を発行する。更新系のdmlを発行後commit、rolbackを行う。 2.メインメニューでは何も行わず、サブ機能でそれぞれ、db接続、dml 発行commitまたは、rolbackしdb切断まで行う。 3.メインメニューで接続を行い、それぞれのサブ機能でsql を発行する。メニューにて終了後発行後commit、rolbackを行いdbを 切断する。 これらの方式によりそのシステムのポリシーが変わってくると思います。 次へ続く
お礼
すみません、こちらのお礼をしていませんでした。
- ToOrisugaru
- ベストアンサー率28% (80/280)
はじめまして、通るすがると申します。 dbcloseにて例外が発生するケースとしては 1.openしないでcloseしようとした。 2.open中にdbタスクが何らかの障害を検出してしんでいる。 3. dbサーバー上にハード的なトラブルがあった・ などあると思います。 これにより、たとえば、close前に更新しようとしてcommitしないでcloseしようと したが、closeにて例外を検出した場合。commitしてcloseしようとしたがclose にて例外を検出したなどの前にどのような操作したかによって対処は変わってくると 思います。 対処方法は、そのシステムのポリシーにより変わってくると思いますので、ここで 何をやるかはいちがいには言えないと思いますが..
お礼
お返事有難うございます。 >close前に更新しようとしてcommitしないでcloseしようとしたが、closeにて例外を検出した場合 こちらはプログラムのバグということでよろしいでしょうか? close前にcommit または rollbackしない実装はないと思うのでこちらは想定していませんでした。 >commitしてcloseしようとしたがcloseにて例外を検出した 質問のケースはこちらになります。 ただrollbackのケースもあるかと思います。 前回書いた例ですが、例外が発生する場所として3つを考えています。 1.SQL実行 または commit または rollback時に例外発生 2.close時に例外発生 3.上記1,2の両方で例外発生 finallyのcloseの例外処理でスローしてしまうと、3のケースで1の例外発生が隠蔽されてしまいます。逆に例外処理でスローしないと、2のケースが例外が発生しているにも関わらずスローされないので問題があります。かといって1の例外の中に2の例外を入れ子にするのはどうかと考えています。例えるならひとつのメソッドから2つの別々のエラーを同時に返却するメソッドになっているようなもので何かおかしいと・・・。 その辺りをシステムのポリシーによると仰っているのかなと思いますが、一般的にどのようにするのかがピンときません。今までのプロジェクトでどうだったかというと、正直な話をいえばclose処理で「エラーになるようなケースはない」という考えに思えます。close処理でのスローは行っているところは記憶にある限りありませんでした。close処理でエラーになる以前にSQL発行で失敗するだろう、というポリシーだったのかもしれません。 通るすがるさんの経験ではどのようなポリシーがあったか、よろしければ教えて頂けないでしょうか。ここら辺のポリシーを決めないといけない場合、自分だったらどうするべきかと悩んでいます。今の時点では2のケースはほぼ有り得ないとし、close処理で例外が発生した場合はログ出力に留めるのがよいのだろうかと考えています。が、自分でもしっくりきませんので、説明する相手がいたらその人もしっくりこないでしょう。 どこかで折り合いをつけないといけないのだとは思いますが、その折り合いをつける際の観点がぴんときていないのでしょうか。
お礼
お返事ありがとうございます。 勉強になります。まだ頭の中が整理し切れていませんが、アドバイス頂いたことをうまく消化できるにようにがんばってみます。 ありがとうございました。