2009-01-28 33 views
3

在我的應用我做follwing事情:當我從另一個進程讀取數據庫時,爲什麼我的Access數據庫不是最新的?

  1. 打開使用Jet/ADO和VB6(.mdb)中一個Access數據庫
  2. 清除和重新填充表用新的數據
  3. 關閉數據庫
  4. 啓動另一個對新數據執行操作的進程。

問題是有時第二個進程找不到新數據。有時表只是空的,有時候RecordCount> 0,但EOF是真的,我不能做MoveFirst或MoveNext。簡而言之:各種奇怪的事情。

我目前的解決方法是在關閉數據庫和啓動第二個進程之間添加一個延遲。

  • 這裏發生了什麼事?
  • 我可以做點什麼嗎? (除了使用不同的數據庫)

回答

6

只是一個猜測,但我可能是由於一個事實,即噴氣發動機採用讀緩存和惰性寫入:

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

「的Microsoft Jet有一個讀緩存每隔將PageTimeout毫秒更新(默認是5000ms = 5秒),它也有一個懶惰的寫入機制,在單獨的線程上對主進程進行操作,從而將更改寫入磁盤異步。這兩種機制有助於提升性能,但在某些需要高併發性的情況下,他們可能會產生問題。「

本文建議使用Jet的RefreshCache方法並將Jet OLEDB:事務提交模式設置爲1毫秒(Jet對DAO的ADO的一個優點是可以在不更改註冊表中的值的情況下更改此設置)。

P.S.你應該考慮編輯Access數據庫(.mdb)來代替'Jet',並使用'Jet'標籤,否則你會從某個SO用戶那裏得到一個評論,這個用戶對這些東西是無聊的:)

+0

這是哪一個用戶? – 2009-01-28 10:22:28

-1

由於第一個進程是打開MDB的唯一進程,因此將文件寫回到文件可能有點懶。即使在你結束這個過程之後,在操作系統回寫未完成的頁面時可能會有延遲,並且這個過程可能發生在過程已經表明它已經完成之後。

我的建議是停止使用Access,而是使用SQL Server 2008 Express。

+0

-1在這種情況下,這是一個糟糕的建議,在任何其他情況下幾乎都沒有幫助。 – 2009-01-28 20:03:48

+0

很糟糕?怎麼會這樣? – AnthonyWJones 2009-01-29 13:50:55

3

This Microsoft Knowledge Base article解釋瞭如何做到這一點。

下面是示例代碼的摘錄。代碼使用來自一個進程的兩個連接,因此您需要將讀取部分拖放到第二個進程中。

  1. 作者必須在寫入數據之前使用ADO的Connection.BeginTrans啓動一個事務。
  2. 作者必須更新數據庫,然後提交事務(使用ADO的Connection.CommitTrans)。
  3. 在嘗試讀取數據之前,讀者必須調用JRO.JetEngine.RefreshCache傳遞它的連接。

請注意JRO.JetEngine是通過向您的VB項目添加對Microsoft Jet和複製對象2.1庫的引用。

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 
相關問題