Поставщик данных .NET Framework для нескольких открытых соединений Oracle - PullRequest
0 голосов
/ 17 января 2012

У меня есть нижеупомянутый код в отдельном файле класса для установления соединения и выполнения транзакций с БД.У меня проблема с открытием нескольких соединений, которые иногда превышают пул соединений.Проходя по коду, я обнаружил, что в цикле есть коды, которые вызывают 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 и удалили вызов ConnectDB и DisconnectDB из функции типа InsertData (...).Похоже, проблема была решена.Но я хотел бы знать, в случае исключения соединение останется открытым?а также 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

1 Ответ

1 голос
/ 17 января 2012

Вы должны закрыть все соединения, как только закончите, несмотря ни на что.

Предложение:

Лучший способ закрыть соединение - это сделать в блоке finally. Чтобы даже в случае возникновения ошибки перехватить ее (при необходимости зарегистрировать) в блоке catch, а затем соединение закроется в блоке finally.

UPDATE

Вы можете поместить один частный статический счетчик в свой класс Connection. Когда когда-либо вызывается ConnectDB(), вы увеличиваете этот счетчик и уменьшаете его в каждом DisconnectDB(). Теперь в ConnectDB() вы проверяете значение счетчика, если оно превышает минимальное пороговое значение, вы выбрасываете ошибку, выполняя этот путь; Вы можете узнать, есть ли в вашем коде неактивное соединение, и выполнить его рефакторинг. На производстве сохраняйте это пороговое значение высоким или игнорируйте его в коде.

...