How To Synchronize Writes and Reads with the Jet OLE DB Provider and ADO

Article translations Article translations
Article ID: 200300
Expand all | Collapse all

Summary

Every ADO connection that uses the Jet OLE DB Provider maintains an independent Jet session. This results in a delay between writes on one connection being read on a second connection, even if you have two connections in the same database application.

This asynchronous write/read behavior is by design. Microsoft Jet uses a page buffering system to provide enhanced database performance and this page buffering system cannot be turned off.

To demonstrate Jet's delayed write/read behavior when using independent ADO connections, run the following code from a button in a simple VB form:

Const USE_SAME_CONNECTION = False

Sub MissedReadsDemo()
Dim conn1 As New ADODB.Connection
Dim conn2 As New ADODB.Connection
Dim rs As New ADODB.recordset
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.
    For i = 1 To 10
        conn1.Execute "insert into tmpTest (id) values (1)", , _
            adExecuteNoRecords + adCmdText
    Next i
    
    ' Attempt to read records using second connection if
    ' USE_SAME_CONNECTION is set to False.
    If (USE_SAME_CONNECTION) Then
        Set rs = conn1.Execute("select * from tmpTest", , adCmdText)
    Else
        Set rs = conn2.Execute("select * from tmpTest", , adCmdText)
    End If
    
    ' Count records in our table (should be 10).
    i = 0
    While Not rs.EOF
        i = i + 1
        rs.MoveNext
    Wend
    rs.Close

    If (USE_SAME_CONNECTION) Then
        MsgBox "Read " & i & " records using same connection."
    Else
        MsgBox "Read " & i & " records using 2 different connections."
    End If
    
    conn1.Close
    conn2.Close

End Sub
				
Note that if you run the above sample code over and over, you will intermittently get 10 records returned or 0 records returned when the USE_SAME_CONNECTION flag is set to False. This demonstrates that writes and reads when using two ADO connections with the Jet OLEDB Provider 4.0 are not completely synchronous. If you set the USE_SAME_CONNECTION flag to True, you will always get 10 records returned. This demonstrates that writes and reads on the same ADO connection are 100% synchronous when using the Jet OLEDB Provider 4.0.

More information

In certain situations you may need to use two separate ADO connections when writing and reading data from an Access database using the Jet OLEDB Provider. For example, if you have two separate processes that are writing and reading to the same Access database, there is no way to share a single connection. In this situation, you can synchronize writes and reads with separate ADO connections if you follow these guidelines:

  1. The writer must start a transaction, using ADO's Connection.BeginTrans, prior to writing the data.
  2. The writer must make the database updates and then commit the transaction (using ADO's Connection.CommitTrans).
  3. The reader must call JRO.JetEngine.RefreshCache passing in it's connection prior to attempting to read the data.
Note that JRO.JetEngine is included by adding a reference to the Microsoft Jet And Replication Objects 2.1 Library to your VB project.

The following code example demonstrates how to synchronize two connections using the above method:

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
				
If you run the above code, you should always get 10 records returned by the reader connection. If you comment out the call to RefreshCache, or do not use the transaction when writing the data, the number of records returned will not always be 10. Following this method will allow synchronized writes and reads between separate processes as well when using ADO with the Microsoft Jet OLE DB Provider 4.0.

Note that this method does not work when using the Microsoft Access ODBC driver with ADO. The Microsoft Access ODBC driver does not allow synchronized writes and reads between two continuously open ADO connections under any circumstance. In order to successfully write and read data using the Microsoft Access ODBC driver with ADO, the writer connection must be closed after the write is complete and the reader connection must be closed and re-opened prior to reading the data. Use the following method to synchronize writes and reads between 2 connections with the Microsoft Access ODBC driver and ADO:

  1. The writer must make the database updates (with or without a transaction) and then close it's connection.
  2. The reader must close and re-open it's connection prior to attempting to read the data.

References

180223 How To Synchronizing Reads and Writes Between Two DAO Processes

Properties

Article ID: 200300 - Last Review: June 22, 2014 - Revision: 3.0
Keywords: 
kbdatabase kbhowto kbjet kbprovider KB200300
Retired KB Content Disclaimer
This article was written about products for which Microsoft no longer offers support. Therefore, this article is offered "as is" and will no longer be updated.

Give Feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com