使用 Jet OLE DB 提供者每個 ADO 連接會維護獨立的 Jet 工作階段。 這會導致一條連線,即使您在相同的資料庫應用程式中有兩個連線,在第二個連線正在讀取的寫入之間的延遲。
此非同步寫入/讀取行為是經過設計規劃的。 Microsoft Jet 使用緩衝處理系統的頁面來提供增強的資料庫的效能並無法關閉緩衝處理系統此頁面。
若要示範 Jet 的延遲的寫入/讀取行為使用獨立的 ADO 連線時,請從簡易的 VB 表單中的按鈕執行下列程式碼:
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
請注意如果您重複執行上述的範例程式碼,您將會間歇地收到 10 記錄傳回或 0 USE_SAME_CONNECTION 旗標設為 False 時,傳回的記錄。 這示範,將寫入和讀取與 Jet OLEDB 提供者 4.0 的兩個 ADO 連線不是完全同步時使用。 如果您將 USE_SAME_CONNECTION 旗標設定為 True 會一律出現 10 個傳回的記錄。 這示範,將寫入和讀取上相同 ADO 連線是使用 Jet OLEDB 提供者 4.0 時的同步的 100%。
在某些情況下,您可能需要撰寫且從 Access 資料庫中使用 Jet OLEDB 提供者讀取資料時,請使用兩個個別的 ADO 連線。 比方說如果您的撰寫和讀取相同的 Access 資料庫的兩個個別處理序沒有方法來共用單一連線。 在這種情況下您可以同步寫入,並讀取與個別的 ADO 連線如果您遵循這些方針:
- 寫入器必須開始一個交易使用 ADO 的 Connection.BeginTrans,之前要寫入資料。
- 寫入器,必須進行資料庫更新並認可交易 (使用 ADO 的 Connection.CommitTrans)。
- 讀取器必須呼叫 JRO.JetEngine.RefreshCache 傳入它的連線之前嘗試讀取資料。
請注意將
Microsoft Jet 及複寫物件 2.1 庫 的參考加入至 VB 專案包含
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
如果您在執行上述程式碼您應該永遠取得 10 個讀取器連線所傳回的記錄。 如果您標記為註解對
RefreshCache,呼叫或寫入資料時,不要使用交易,傳回的記錄筆數不一定會 10。 遵循此方法將允許同步的寫入和讀取不同的處理序之間使用 ADO 與 [Microsoft Jet OLE DB 提供者 4.0 時。
請注意這個方法不適用當搭配 ADO 使用 Microsoft Access ODBC 驅動程式。 Microsoft Access ODBC 驅動程式不允許同步的寫入和讀取在任何情況下的兩個連續開啟 ADO 連線之間。 為了要成功地寫入及讀取資料搭配 ADO 使用 Microsoft Access ODBC 驅動程式,寫入已完成,並讀取器連線必須關閉並重新開啟之前要讀取資料後必須關閉寫入器連接。 使用下列方法將同步處理會寫入,然後再讀取 2 的連線,而 Microsoft Access ODBC 驅動程式和 ADO 之間:
- 寫入器必須進行資料庫更新 (含或不使用交易),然後關閉它的連線。
- 讀取器必須關閉並重新開啟它的連線之前嘗試讀取資料。