2012-01-17 19 views
0

接続を確立し、DBトランザクションを実行するために、以下のコードを別々のクラスファイルに作成しました。私はいつか接続プールを超える複数の接続が開かれている問題があります。コードを踏んだとき、ConnectDB()をループで呼び出すコードがあり、DisconnectDB()を呼び出さないことがわかりました。しかし、私は条件OraConn.State = ConnectionState.Closedが状況を処理する必要があると予想した。どういうわけか、条件は常に満たされ、別の接続を開くことになります。私はどこに間違っているのか、ここではどのようなベストプラクティスを採用することができるかを提案できますか?複数のオープンな接続のための.NET Frameworkデータプロバイダ

Public Class Connection 
Dim Str_conn As String = "Data Source=...; User=...; password=...; Min Pool Size=10; Max Pool Size=500;" 
Public OraConn As OracleConnection 
Dim cmd As OracleCommand 
Dim dr As OracleDataReader 
Dim data_adapt As OracleDataAdapter 
Dim dt As DataTable 
Dim ds As DataSet 

Public Sub ConnectDB() 
    OraConn = New OracleConnection(Str_conn) 
    If OraConn.State = ConnectionState.Closed Then 
     OraConn.Open() 
    End If 
End Sub 

Public Sub DisconnectDB() 
    If OraConn.State = ConnectionState.Open Then 
     OraConn.Close() 
    End If 
End Sub 

Public Function get_dataset(ByVal query As String, ByRef ds As DataSet) As DataSet 
    data_adapt = New OracleDataAdapter(query, OraConn) 
    data_adapt.Fill(ds) 
    Return ds 
End Function 

Public Function get_datareader(ByVal query As String) As OracleDataReader 
    cmd = New OracleCommand(query, OraConn) 
    dr = cmd.ExecuteReader() 
    Return dr 
End Function 

Public Sub UpdateDB(ByVal query As String) 
    cmd = New OracleCommand(query, OraConn) 
    cmd.ExecuteNonQuery() 
    cmd.Dispose() 
End Sub 

このクラスは他のクラスで参照されるか、このようなaspx.vbページで直接参照されます。

Public Function InsertData(ByVal var1 As String, ByVal var2 As String) As Integer 
    conn.ConnectDB() 
    Dim qryInsert As String 

    qryInsert = " INSERT INTO TABLE VALUES ('" & var1 & "', " 
    qryInsert = qryInsert & var2 & "')"   

    Try 
     conn.UpdateDB(qryInsert) 
    Catch ex As OracleException 
     If ex.Code = 1 Then 
      updData(var1, var2) 
     ElseIf ex.Code = 2091 Then 
      msgprompt("Duplicate Unique Key!", "Warning") 
     End If 
    Finally 
     conn.DisconnectDB() 
    End Try 
    Return count 
End Function 

接続は、機能updData()で再度開きます。私はそれが正しく閉じられる必要があることを理解しているが、すべての開発者にタブを維持することは不可能である。したがって、同じ接続を使用して接続クラスから直接制御したいが、条件If OraConn.State = ConnectionState.Closedは役に立たない。

UPDATE

私が使用してブロックの下にはupdatedbでコードを入れて、InsertData(...)のような関数からのconnectDBとDisconnectDBへの呼び出しを削除しました。問題は解決したようです。しかし、私は例外の場合に接続が開いたままになることを知りたいですか?また、OraConnはUsingブロックの中で定義されたpublic変数なので、GCによって処分されますか?

Public Sub UpdateDB(ByVal query As String) 
    Using OraConn = New OracleConnection(Str_conn) 
     cmd = New OracleCommand(query, OraConn) 
     Try 
      OraConn.Open() 
      cmd.ExecuteNonQuery() 
     Catch ex As Exception 
      Throw 
     Finally 
      cmd.Dispose() 
     End Try 
    End Using 
End Sub 
+0

どこでConnectDBを呼び出していますか? – Harsh

+0

DataSource、ユーザー名、およびパスワードの設定だけで簡単な接続を作成することはできません。あなたが接続を有効にするプールを再利用できるようにしたい場合。具体的には、 'Enlist'と' Pooling'を有効にしてみてください。詳細については、[OracleConnection.ConnectionString](http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oracleconnection.connectionstring.aspx)を参照してください。 –

+0

@ GeekOnDemand私は自分の投稿を編集してConnectDB – Nilanjan

答えて

1

すべての接続を終了するとすぐに、すべての接続を終了する必要があります。

提案:

接続を閉じるためのベストプラクティスは、finallyブロックでそれを行うことです。だからエラーがあっても、それをキャッチ(必要ならばログ)してcatchブロックに入れてから、finallyブロックに接続が閉じられるようにしてください。

UPDATE

あなたConnectionクラスで1つのプライベート静的カウンターを置くことができます。いつでもConnectDB()が呼び出されると、このカウンタがインクリメントされ、DisconnectDB()で減少します。今度はConnectDB()で、カウンタの値をチェックします。このようにすれば、エラーが発生する最小のしきい値を超えた場合です。コード内のアイドル状態の接続を知り、リファクタリングすることができます。生産時には、このしきい値を高く保つか、コードで無視してください。

+0

入力していただきありがとうございます。 – Nilanjan

関連する問題