当我从另一个进程读取时,为什么我的Access数据库不是最新的?

时间:2009-01-28 09:07:12

标签: ms-access vb6 ado jet

在我的申请中,我做了以下事情:

  1. 使用Jet / ADO和VB6
  2. 打开Access数据库(.mdb)
  3. 使用新数据清除并重新填充表格
  4. 关闭数据库
  5. 启动另一个处理新数据的过程。
  6. 问题是有时第二个进程无法找到新数据。有时表只是空的,有时RecordCount> 0,但EOF是真的,我不能做MoveFirst或MoveNext。简而言之:各种奇怪的事情。

    我目前的解决方法是在关闭数据库和启动第二个进程之间添加延迟。

    • 这里发生了什么事?
    • 我可以为此做些什么吗? (除了使用不同的数据库)

3 个答案:

答案 0 :(得分:7)

只是一个猜测,但我可能是因为Jet引擎具有读取缓存和惰性写入这一事实:

How To Implement Multiuser Custom Counters in Jet 4.0 and ADO 2.1

“Microsoft Jet有一个读取缓存,每隔PageTimeout毫秒更新一次(默认为5000毫秒= 5秒)。它还有一个惰性写入机制,它在与主处理的单独线程上运行,从而异步地将更改写入磁盘这两种机制有助于提升性能,但在某些需要高并发性的情况下,它们可能会产生问题。“

本文建议使用Jet的RefreshCache方法并将Jet OLEDB:事务提交模式设置为1毫秒(对于Jet,ADO优于DAO的一个优点是您可以在不更改注册表中的值的情况下更改此设置)。

P.S。你应该考虑编辑Access数据库(.mdb)来提及'Jet'而不是使用'Jet'标签,否则你会得到某些SO用户的评论,这些用户对这些事情是不诚实的:)

答案 1 :(得分:3)

Microsoft Knowledge Base article解释了如何做到这一点。

以下是示例代码的摘录。代码使用来自一个进程的两个连接,因此您需要将读取部分拉入第二个进程。

  1. 在编写数据之前,编写者必须使用ADO的Connection.BeginTrans启动事务。
  2. 编写者必须进行数据库更新,然后提交事务(使用ADO的Connection.CommitTrans)。
  3. 在尝试读取数据之前,读者必须调用JRO.JetEngine.RefreshCache传递连接。
  4. 请注意,通过向VB项目添加对Microsoft Jet和复制对象2.1库的引用来包含JRO.JetEngine。

        Sub SyncReadDemo()
        Dim conn1 As New ADODB.Connection
        Dim conn2 As New ADODB.Connection
        Dim rs As New ADODB.recordset
        Dim JRO As New JRO.JetEngine
        Dim strConnect As String
        Dim i As Long
    
    
      ' Set up our connection string (requires a database named c:\db1.mdb).
        strConnect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\db1.mdb"
    
        ' Open connection 1 and drop and re-create test table.
        conn1.CursorLocation = adUseServer
        conn1.Open strConnect
        On Error Resume Next
        conn1.Execute "drop table tmpTest", , _
            adExecuteNoRecords + adCmdText
        On Error GoTo 0
        conn1.Execute "create table tmpTest (id long)", , _
            adExecuteNoRecords + adCmdText
    
        ' Close connection 1 to flush the creation of table tmpTest. 
        conn1.Close
    
        ' Now open connection 1 and connection 2.
        conn1.Open strConnect
        conn2.Open strConnect
    
        ' Insert 10 records using connection 1.
        ' Note we must perform all writes inside of a transaction.
        conn1.BeginTrans
        For i = 1 To 10
            conn1.Execute "insert into tmpTest (id) values (1)", , _
                adExecuteNoRecords + adCmdText
        Next i
        conn1.CommitTrans
    
        ' Refresh cache for reader connection.
        JRO.RefreshCache conn2
        Set rs = conn2.Execute("select * from tmpTest", , adCmdText)
    
        ' Count records in our table (should be 10).
        i = 0
        While Not rs.EOF
            i = i + 1
            rs.MoveNext
        Wend
        rs.Close
    
        MsgBox "Read " & i & " records using different connections."
    
        conn1.Close
        conn2.Close
    
    End Sub
    

答案 2 :(得分:-1)

由于第一个进程是打开MDB的唯一进程,因此将内容写回文件可能有点懒惰。即使你结束了这个过程,也会有一个延迟,而操作系统会回写未完成的页面,这可能发生在该过程发出信号已经完成之后。

我的建议是,停止使用Access,改为使用SQL Server 2008 Express。