QA@IT

VB.NETのマルチスレッド毎にORASESSIONを確立するには??

3825 PV

VB.NETのマルチスレッドでORACLEDBにUPDATEを並列的にするアプリケーションを作っています。

WEBアプリなどではAPサーバー上の同じアプリをスレッドを複数作って並列処理などしてDBに更新・参照していると思いますが、
グローバルにセッションを作らずに、スレッド毎に同じ変数を定義して、セッションを確立しているのでしょうか?

回答

質問の内容がよくわからなかったので失礼ながら履歴を参照させてもらいました。

VB.NETのマルチスレッドでORACLEDBにUPDATEを並列的にするアプリケーションを作っています。
配列の一番前から順に取り出し、次々UPDATE処理を何百件と行うものです。
(略)
しかし、1~2百件処理したときにエラーが発生します。(※それまでの分はちゃんと更新されています。)

同時接続数のエラーではないかと思います。
セッションの上限はどうなっていますか?
また、ソースをみるにCOMオブジェクト(ADO.NETではなくADOやoo4oなど)を利用しているようですが、
Marshal.ReleaseComObjectなどを利用してきちんと解放できていますか?

Try
    OraSession.BeginTrans()
    strSQL = "UPDATE HINMST SET ENDFLG = 1 WHERE MAKERCODE = '" & FACTOR1 & "'"

    OraDatabase.ExecuteSQL(strSQL) 'まず、ここでエラーが発生する。(SQL実行エラー?)

Catch

    OraSession.Rollback() 'そのあと、ここでエラーが発生する(※「ComErrorExceptionがハンドルされませんでした。」「ロールバックするオブジェクトが存在しません。」というエラー)

    Exit Sub
End Try

Catchブロックでのエラー原因がわからないとのことですが、
おそらくBeginTransで例外が発生して、トランザクションが開始できていないのにRollbackしているからだと思います。

Catchブロックでもきちんと例外を補足して、最初に起きているメッセージも参照した方が良いでしょう。
たとえば以下の様にしてメッセージを確認してください

Catch ex As Exception
    MessageBox.Show(ex.Message)
    ' または Debug.Print(ex.Message)

※ この部分は最終的にはアプリケーションの都合の合う形に変えてください。
※ 最終的に Exceptionインスタンスを参照する必要がないのであればCatchだけのままの方が正しいです。


11/1 追記

ちなみに Webアプリなどではコネクションプーリングを行うことが多いと思います。
ただどこに処理があるかとか使う目的、環境にもよってきますのでいつでもこれでどうぞというわけでもありません。
維持リソースのコストと接続を作り直すコスト(排他にかかるコストも含む)、実際にパフォーマンスがどうなるかなども絡んできます。

編集 履歴 (2)
ウォッチ

この質問への回答やコメントをメールでお知らせします。