【问题标题】:.NET Framework Data Provider for Oracle multiple open connection.NET Framework Data Provider for Oracle 多打开连接
【发布时间】:2012-01-17 06:52:43
【问题描述】:

我在一个单独的类文件中有下面提到的代码,用于建立连接和执行数据库事务。我有一个问题,即打开的多个连接有时超过了连接池。当我单步执行代码时,我发现有些代码在循环中调用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

【问题讨论】:

  • 你在哪里打电话给 ConnectDB ?
  • 仅使用数据源、用户名和密码集创建简单连接是行不通的。如果您希望能够重用连接启用池。具体来说,尝试启用EnlistPooling。更多详情请查看OracleConnection.ConnectionString
  • @GeekOnDemand 我已经编辑了我的帖子以显示如何调用 ConnectDB
  • 您在使用时是否收到任何错误消息?
  • @Nikola AFAIK 池在 .NET 数据提供程序中默认启用

标签: asp.net vb.net oracle connection-pooling oracleclient


【解决方案1】:

无论如何,您必须在完成后立即关闭所有连接。

建议:

关闭连接的最佳做法是在finally 块中进行。这样即使有任何错误,在catch 块中捕获它(如果需要,记录它),然后连接将在finally 块中关闭。

更新

您可以在 Connection 类中放置一个私有静态计数器。当ConnectDB() 被调用时,你会增加这个计数器并在每个DisconnectDB() 中减少它。现在在ConnectDB() 中检查计数器的值,如果它超过最小阈值,则通过这种方式抛出错误;您可以了解代码中存在的空闲连接并对其进行重构。在生产环境中保持此阈值较高或在代码中忽略它。

【讨论】:

  • 感谢您的意见。我将实施计数器以避免将来出现连接问题。
猜你喜欢
  • 2015-12-24
  • 1970-01-01
  • 2018-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-19
相关资源
最近更新 更多