0

接続を確立してDBトランザクションを実行するために、別のクラスファイルに以下のコードがあります。複数の接続が開かれ、接続プールを超えることがあるという問題があります。ConnectDB()コードをステップスルーすると、を呼び出さずにループで呼び出すコードがあることがわかりましたDisconnectDB()。しかし、私はその状態OraConn.State = ConnectionState.Closedが状況を処理するはずだと思っていました。どういうわけか、条件は常に満たされているため、別の接続セットが開かれます。どこが間違っているのか、またここでどのようなベストプラクティスを採用できるのかを提案できますか?

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が役に立たないのです。

アップデート

UpdateDBのUsingブロックの下にコードを配置し、InsertData(...)などの関数からConnectDBとDisconnectDBへの呼び出しを削除しました。問題は解決したようです。しかし、例外が発生した場合、接続は開いたままになりますか?また、OraConnはUsingブロックの外部で定義されたパブリック変数なので、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
4

1 に答える 1

1

何があっても、使い終わったらすぐにすべての接続を閉じる必要があります。

提案:

接続を閉じるためのベストプラクティスは、finallyブロックで行うことです。エラーが発生した場合でも、ブロックでキャッチ(必要に応じてログに記録)すると、catchブロックで接続が終了しfinallyます。

アップデート

クラスに1つのプライベート静的カウンターを置くことができますConnectionConnectDB()呼び出されるたびに、このカウンターをインクリメントし、ごとにデクリメントしますDisconnectDB()。ここでConnectDB()、counterの値を確認します。最小しきい値を超えている場合は、この方法でエラーをスローします。コードに存在するアイドル接続を認識し、リファクタリングすることができます。本番環境では、このしきい値を高く保つか、コードで無視してください。

于 2012-01-17T06:58:18.820 に答える