Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Gilt für: Access 2013, Office 2013
Erkennen und Lösen von Konflikten
Wenn Sie das Recordset -Objekt im sofortigen Aktualisierungsmodus verwenden, ist die Wahrscheinlichkeit von Parallelitätsproblemen wesentlich geringer. Wenn die Anwendung andererseits den Batchaktualisierungsmodus verwendet, besteht eine relativ hohe Wahrscheinlichkeit, dass ein Benutzer einen Datensatz ändert, bevor Änderungen eines anderen Benutzers, der denselben Datensatz bearbeitet, gespeichert werden. In diesem Fall sollte der Konflikt von der Anwendung problemlos behoben werden. Es kann Ihr Wunsch sein, dass die letzte Person, die ein Update an den Server sendet, "gewinnt". Oder Sie möchten dem letzten Benutzer die Entscheidung überlassen, welches Update Vorrang haben soll, indem Sie ihm eine Wahl zwischen den beiden in Konflikt stehenden Werten geben.
In jedem Fall stellt ADO die Eigenschaften UnderlyingValue und OriginalValue des Field -Objekts für diese Art von Konflikten bereit. Verwenden Sie diese Eigenschaften in Kombination mit der Resync-Methode und der Filter-Eigenschaft des Recordset-Objekts.
Erkennen von Fehlern
Wenn ADO während eines Batchupdates auf einen Konflikt stößt, wird eine Warnung in die Errors-Auflistung eingefügt. Daher sollten Sie immer unmittelbar nach dem Aufrufen von BatchUpdate nach Fehlern suchen und wenn Sie diese finden, mit dem Testen der Annahme beginnen, dass ein Konflikt aufgetreten ist. Der erste Schritt besteht darin, die Filter-Eigenschaft für das Recordset auf adFilterConflictingRecords festzulegen (die Filter-Eigenschaft wird im vorherigen Kapitel erläutert). Dadurch wird die Ansicht ihres Recordset-Objekts auf die Datensätze beschränkt, die in Konflikt stehen. Wenn die RecordCount-Eigenschaft nach diesem Schritt gleich 0 ist, wissen Sie, dass der Fehler durch etwas anderes als einen Konflikt ausgelöst wurde.
Wenn Sie BatchUpdate aufrufen, generieren ADO und der Anbieter SQL-Anweisungen, um Aktualisierungen in der Datenquelle auszuführen. Beachten Sie, dass für bestimmte Datenquellen Einschränkungen bezüglich der Spaltentypen gelten, die in einer WHERE-Klausel verwendet werden können.
Rufen Sie anschließend die Resync-Methode für das Recordset-Objekt auf, wobei das Argument AffectRecords auf adAffectGroup sowie das Argument ResyncValues auf adResyncUnderlyingValues festgelegt sind. Die Resync-Methode aktualisiert die Daten im aktuellen Recordset-Objekt in der zugrunde liegenden Datenbank. Mithilfe von adAffectGroup stellen Sie sicher, dass nur die Datensätze, die mit der aktuellen Filtereinstellung angezeigt werden (also nur die miteinander in Konflikt stehenden Datensätze), erneut mit der Datenbank synchronisiert werden. Dies könnte bei einem umfangreichen Recordset-Objekt einen erheblichen Unterschied hinsichtlich der Leistung ausmachen. Wenn Sie beim Aufrufen von Resync das Argument ResyncValues auf adResyncUnderlyingValues festlegen, stellen Sie sicher, dass die UnderlyingValue-Eigenschaft den Wert (der den Konflikt verursacht) aus der Datenbank enthält, dass die Value-Eigenschaft den vom Benutzer eingegebenen Wert beibehält und dass die OriginalValue-Eigenschaft den ursprünglichen Wert für das Feld enthält (der Wert, der vor dem letzten erfolgreichen UpdateBatch-Aufruf vorhanden war). Anschließend können Sie mithilfe dieser Werte den Konflikt programmgesteuert lösen oder den Benutzer auffordern, den gewünschten Wert auszuwählen.
Diese Technik wird im folgenden Codebeispiel dargestellt. In diesem Beispiel wird künstlich ein Konflikt erzeugt, indem mithilfe eines separaten Recordset -Objekts ein Wert in der zugrunde liegenden Tabelle geändert wird, bevor UpdateBatch aufgerufen wird.
'BeginConflicts
On Error GoTo ErrHandler:
Dim objRs1 As New ADODB.Recordset
Dim objRs2 As New ADODB.Recordset
Dim strSQL As String
Dim strMsg As String
strSQL = "SELECT * FROM Shippers WHERE ShipperID = 2"
'Open Rs and change a value
objRs1.CursorLocation = adUseClient
objRs1.Open strSQL, strConn, adOpenStatic, adLockBatchOptimistic, adCmdText
objRs1("Phone") = "(111) 555-1111"
'Introduce a conflict at the db...
objRs2.Open strSQL, strConn, adOpenKeyset, adLockOptimistic, adCmdText
objRs2("Phone") = "(999) 555-9999"
objRs2.Update
objRs2.Close
Set objRs2 = Nothing
On Error Resume Next
objRs1.UpdateBatch
If objRs1.ActiveConnection.Errors.Count <> 0 Then
Dim intConflicts As Integer
intConflicts = 0
objRs1.Filter = adFilterConflictingRecords
intConflicts = objRs1.RecordCount
'Resync so we can see the UnderlyingValue and offer user a choice.
'This sample only displays all three values and resets to original.
objRs1.Resync adAffectGroup, adResyncUnderlyingValues
If intConflicts > 0 Then
strMsg = "A conflict occurred with updates for " & intConflicts & _
" record(s)." & vbCrLf & "The values will be restored" & _
" to their original values." & vbCrLf & vbCrLf
objRs1.MoveFirst
While Not objRs1.EOF
strMsg = strMsg & "SHIPPER = " & objRs1("CompanyName") & vbCrLf
strMsg = strMsg & "Value = " & objRs1("Phone").Value & vbCrLf
strMsg = strMsg & "UnderlyingValue = " & _
objRs1("Phone").UnderlyingValue & vbCrLf
strMsg = strMsg & "OriginalValue = " & _
objRs1("Phone").OriginalValue & vbCrLf
strMsg = strMsg & vbCrLf & "Original value has been restored."
MsgBox strMsg, vbOKOnly, _
"Conflict " & objRs1.AbsolutePosition & _
" of " & intConflicts
objRs1("Phone").Value = objRs1("Phone").OriginalValue
objRs1.MoveNext
Wend
objRs1.UpdateBatch adAffectGroup
Else
'Other error occurred. Minimal handling in this example.
strMsg = "Errors occurred during the update. " & _
objRs1.ActiveConnection.Errors(0).Number & " " & _
objRs1.ActiveConnection.Errors(0).Description
End If
On Error GoTo 0
End If
objRs1.MoveFirst
'Clean up
objRs1.Close
Set objRs1 = Nothing
Exit Sub
ErrHandler:
If Not objRs1 Is Nothing Then
If objRs1.State = adStateOpen Then objRs1.Close
Set objRs1 = Nothing
End If
If Not objRs2 Is Nothing Then
If objRs2.State = adStateOpen Then objRs2.Close
Set objRs2 = Nothing
End If
If Err <> 0 Then
MsgBox Err.Source & "-->" & Err.Description, , "Error"
End If
'EndConflicts
Mit der Status -Eigenschaft des aktuellen Record -Objekts oder eines bestimmten Field -Objekts können Sie ermitteln, welche Art von Konflikt aufgetreten ist.
Ausführlichere Informationen zur Fehlerbehandlung finden Sie in Kapitel 6: Fehlerbehandlung.