Поставщик данных .NET Framework для нескольких открытых подключений Oracle

У меня есть приведенный ниже код в отдельном файле класса для установления соединения и выполнения транзакций БД. У меня проблема, когда открывается несколько соединений, которые иногда превышают пул соединений. Когда я прошел через код, я обнаружил, что есть коды, которые вызывают 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, поэтому будет ли она удалена сборщиком мусора?

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

person Nilanjan    schedule 17.01.2012    source источник
comment
Куда вы звоните в ConnectDB?   -  person Harsh    schedule 17.01.2012
comment
Создание простых соединений с использованием только DataSource, Username и Password не будет работать. Если вы хотите иметь возможность повторно использовать соединение, включите пул. В частности, попробуйте включить Enlist и Pooling. Для получения дополнительных сведений см. OracleConnection.ConnectionString   -  person Nikola Radosavljević    schedule 17.01.2012
comment
@GeekOnDemand Я отредактировал свой пост, чтобы показать, как вызывается ConnectDB   -  person Nilanjan    schedule 17.01.2012
comment
Вы получаете сообщение об ошибке при использовании этого?   -  person Harsh    schedule 17.01.2012
comment
Пул @Nikola AFAIK включен по умолчанию в поставщике данных .NET.   -  person Nilanjan    schedule 18.01.2012
comment
@GeekOnDemand Исключением является время ожидания истекло. Время ожидания истекло до получения соединения из пула.   -  person Nilanjan    schedule 18.01.2012
comment
По умолчанию пул включен, но в вашем первом посте я не увидел строки подключения. Как вы сами сказали, соединение должно быть закрыто, чтобы пул функционировал должным образом. Если вы не можете постоянно проверять своих разработчиков, вы можете ограничить их возможности по написанию ошибочного кода. Например. не позволяйте им использовать OracleConnection, но создайте собственный OracleConnectionScope, который они будут использовать вместо соединения. При удалении области действия закройте соединение, чтобы это было сделано в конце блока using. Вам просто НЕОБХОДИМО закрыть соединения, если пула соединений 500 недостаточно, извините :)   -  person Nikola Radosavljević    schedule 18.01.2012


Ответы (1)


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

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

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

ОБНОВЛЕНИЕ

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

person Amar Palsapure    schedule 17.01.2012
comment
Спасибо за вклад. Я буду использовать счетчик, чтобы избежать проблем с подключением в будущем. - person Nilanjan; 18.01.2012