1

我们正在从 MS Access 迁移到现代 DBMS,但与此同时,我遇到了一个我找不到解决方案或解释的问题。

通常,打开 OleDBConnection 会生成一个锁定文件,该文件会在池中的最后一个连接关闭后挂起 1 分钟。如果您检查此文件,它会提供一些有关锁定过程等的信息。通常(在我们代码的所有其他部分中),这只会在锁定文件中产生一个条目,而不管在同样的过程,很好。

我使用完全相同的连接字符串开发了一些新功能,这似乎在此锁定文件中为每个 connection.open() 建立了一个新条目。我非常确定所有资源都在每个方法的 finally 块中关闭。更糟糕的是,如果我重新加载页面,它会产生一个额外的集合,直到您达到 255 个打开连接/锁的硬限制。

在这个和许多其他领域我可以看到的唯一区别是我在到达 finally 块之前加载了子对象。以下模式继续下跌约 3 个水平。我正在加载一个模板来构建一个数据输入表单,所以我并不十分关心效率。

有没有人在他们的 ldb/laccdb 文件中遇到过这种相同条目的堆积?谢谢

Provider=Microsoft.ACE.OLEDB.12.0;Data Source='...\db.accdb';Persist Security Info=False;OLE DB Services=-1;
...
Public Overrides Function load(ByVal DB_ID As Integer) As Boolean
        Dim connection As OleDbConnection
        connection = New OleDbConnection(connStr)
        Dim reader As OleDbDataReader = Nothing
        Try
            Dim loadCMD As New OleDbCommand(String.Format("SELECT * FROM {0} WHERE ID = @db_ID", tableName), connection)
            loadCMD.Parameters.AddWithValue("@db_ID", DB_ID)
            connection.Open()
            reader = loadCMD.ExecuteReader()
            If reader.Read() Then
                ID = GetNullSafeValue(reader(Schema.FormSections.ID), GetType(Integer), failure)
                FormID = GetNullSafeValue(reader(Schema.FormSections.FormID), GetType(Integer), failure)
                SectionTitle = GetNullSafeValue(reader(Schema.FormSections.SectionTitle), GetType(String))
                Expanded = GetNullSafeValue(reader(Schema.FormSections.Expanded), GetType(Boolean))
                ServiceURL = GetNullSafeValue(reader(Schema.FormSections.ServiceURL), GetType(String))
                SectionOrder = GetNullSafeValue(reader(Schema.FormSections.SectionOrder), GetType(Integer), failure)
                Rows = FormRow.loadAllForSection(ID, config)
                Return True
            End If
        Catch ex As Exception
            ExceptionHandler(ex, config)
        Finally
            If reader IsNot Nothing Then
                reader.Close()
            End If
            connection.Close()
        End Try
        Return False
    End Function
...
Public Shared Function loadAllForSection(ByVal db_SectionID As Integer, ByVal cfg As ReportManagerConfiguration) As List(Of FormRow)
    Dim retList As New List(Of FormRow)
    Dim connection As OleDbConnection
    connection = New OleDbConnection(cfg.RM_LabConfig.connString)
    Dim reader As OleDbDataReader = Nothing
    Try
        Dim loadAll As New OleDbCommand(String.Format("SELECT ID FROM {0} WHERE SectionID = @db_sID ORDER BY RowNumber ASC", cfg.RM_LabConfig.FormRowsTable), connection)
        loadAll.Parameters.AddWithValue("@db_sID", db_SectionID)
        connection.Open()
        reader = loadAll.ExecuteReader()
        While reader.Read
            Dim thisRow As New FormRow(cfg)
            thisRow.load(GetNullSafeValue(reader(Schema.FormRows.ID), GetType(Integer), failure))
            If thisRow.ID <> failure Then
                retList.Add(thisRow)
            End If
        End While
    Catch ex As Exception
        ExceptionHandler(ex, cfg)
    Finally
        If reader IsNot Nothing Then
            reader.Close()
        End If
        connection.Close()
    End Try
    Return retList
End Function
4

2 回答 2

0

我不确定这一点,但我正在尝试回答您的问题。

尝试在 Try Block 和 In finally 块中关闭连接,检查连接是否已打开。如果已经打开,则关闭它。

于 2013-05-15T20:38:13.617 回答
0

通过实验,我已经能够确定锁定的建立是由于在外部调用释放连接之前在其他函数调用中创建新连接引起的。

解决方案是以确保连接在进入较低级别之前关闭的方式对其进行重写。

唯一没有解释的是为什么重新运行查询会进一步构建列表。连接最终关闭了,所以我预计它下次会使用这些插槽。

于 2013-05-16T18:02:09.797 回答