Закрытие соединения с Oracle в VB.NET - PullRequest
1 голос
/ 13 августа 2011

В моей программе я получил несколько мест, где я открываю соединение с базой данных Oracle, читаю некоторые строки с помощью хранимой процедуры, которая возвращает мне курсор, помещает их в IDataReader, закрывает соединение и продолжает.

Теперь все работает нормально до момента закрытия соединения.Я наблюдал за соединениями, открытыми с базой данных через TOAD для Oracle, и выяснил, что база данных, кажется, сохраняет соединение открытым после того, как я сказал m_Connection.Close и m_Connection.Dispose.

Я использую Oracle.DataAccess и через короткое время получаю сообщение о том, что существует множество соединений.Я отладил свой сеанс и убедился, что vb выполняет команду close () и делает это, но база данных нет.Кто-нибудь получил идею, как это исправить?

1 Ответ

1 голос
/ 13 августа 2011

В .Net вам нужно обернуть соединения с базой данных в блок Try / Catch / finally и всегда закрывать соединения в разделе, наконец.Для этого существует сокращение, называемое Using блоком.Это означает, что поддерживать соединение в качестве члена класса (как вы, кажется, делаете) почти всегда неверно..Net оптимизирован таким образом, что для каждого запроса лучше создавать новое соединение и объект команды.

DataReaders немного особенный: если вы возвращаете устройство чтения данных из блока, соединение может быть закрыто до вашего DataReader.сделано с этимВ C # я обычно обхожу проблему с помощью итератора (yield return).Поскольку в VB.Net отсутствует поддержка этой конструкции, я мог бы вместо этого использовать Action(Of IDataRecord), например:

Public Sub MyOracleQuery(ByVal id As Integer, ByVal ProcessRecord As Action(Of IDataRecord))
    Dim sql As String = "SELECT <columns> FROM MyTable WHERE ID= @Id"
    Using cn As New OracleConnection("connection string"), _
          cmd As New OracleCommand(sql, cn)

        cmd.Parameters.Add("@Id", SqlDbTypes.Int).Value = id
        cn.Open()

        Using (rdr As IDataReader = cmd.ExecuteReader())
            While rdr.Read()
                ProcessRecord(rdr)
            End While
        End Using
    End Using
End Sub

Теперь вы можете передавать анонимный метод в этот код при его вызове:

Dim id As Integer
If Integer.TryParse(IDTextBox.Text, id) Then
    MyOracleQuery(id, _
        Function(r)
            ''#... Do something with each "r" here
        End Function _
    )
Else
    ''# Complain to user about invalid ID
End If

Обратите внимание, что для этого требуется многопоточный анонимный метод Visual Studio 2010 / .Net 4.Для более старых платформ вы можете объявить метод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...