Standardmäßig sperrt dbmlsync die zu synchronisierenden Tabellen, bevor Upload-Skripten aufgerufen werden, und hält diese Sperren aufrecht, bis der Download festgeschrieben wurde. Sie können die Tabellensperre verhindern, indem Sie die erweiterte Option LockTables auf "off" setzen.
Wir empfehlen, grundsätzlich das Standardverhalten für die Tabellensperre zu aktivieren. Bei skriptgesteuerten Uploads ohne Tabellensperren erhöht sich das Risiko von Problemen und der Schwierigkeitsgrad bei der Erarbeitung einer sauberen und durchführbaren Lösung. Nur erfahrene Anwender mit umfassenden Kenntnissen im Bereich der Datenbankparallelität und der Synchronisationskonzepte sollten vom Standardverhalten abweichende Einstellungen vornehmen.
Wenn die Tabellensperren deaktiviert sind, ist die Isolationsstufe, unter der der Upload gespeicherter Prozeduren erfolgt, besonders wichtig, weil damit festgelegt wird, wie nicht festgeschriebene Transaktionen verwaltet werden. Dies ist kein Problem, wenn Tabellensperren aktiviert sind, weil Tabellensperren dafür sorgen, dass keine nicht festgeschriebenen Änderungen in den synchronisierten Tabellen vorhanden sind, wenn der Upload aufgebaut wird.
Ihre gespeicherten Upload-Prozeduren werden auf der Standardisolationsstufe für den Datenbankbenutzer ausgeführt, der in der dbmlsync-Befehlszeile angegeben ist, sofern Sie die Isolationsstufe nicht ausdrücklich in der gespeicherten Upload-Prozedur geändert haben.
Isolationsstufe 0 ist zwar die Standardisolationsstufe für die Datenbank, es wird aber empfohlen, dass Sie Ihre Upload-Prozeduren nicht auf Isolationsstufe 0 ausführen, wenn Sie skriptgesteuerte Uploads ohne Tabellensperren ausführen. Wenn Sie skriptgesteuerte Uploads ohne Tabellensperren implementieren und Isolationsstufe 0 verwenden, können Sie einen Upload von Änderungen vornehmen, die nicht festgeschrieben wurden, woraus sich folgende Probleme ergeben könnten:
Die nicht festgeschriebenen Änderungen können zurückgesetzt werden, was zur Folge hat, dass falsche Daten in die konsolidierte Datenbank eingelesen werden.
Die nicht festgeschriebene Transaktion ist möglicherweise nicht vollständig, sodass der Upload nur einen Teil einer Transaktion enthält und die konsolidierte Datenbank inkonsistent wird.
Als Alternative können Sie Isolationsstufen 1, 2, 3 oder snapshot verwenden. Bei allen Isolationsstufen wird sichergestellt, dass kein Upload einer nicht festgeschriebenen Transaktion erfolgt.
Wenn Sie Isolationsstufen 1, 2 oder 3 verwenden, kann dies dazu führen, dass Ihre gespeicherten Upload-Prozeduren blockieren, wenn nicht festgeschriebene Änderungen in der Tabelle vorhanden sind. Da Ihre gespeicherten Upload-Prozeduren aufgerufen werden, während dbmlsync mit dem MobiLink-Server verbunden ist, kann dies Serververbindungen binden. Wenn Sie Isolationsstufe 1 verwenden, können Sie das Blockieren verhindern, indem Sie die Tabellen-Hint-Klausel READPAST in Ihren Anweisungen verwenden.
Snapshot-Isolation ist eine gute Alternative, da sie sowohl das Blockieren als auch das Lesen von nicht festgeschriebenen Änderungen verhindert.
Wenn Sie sich dafür entscheiden, Tabellensperren zu deaktivieren, müssen Sie einen Mechanismus verwenden, mit dem Sie Vorgänge verarbeiten können, die beim Eintritt einer Synchronisation nicht festgeschrieben sind. Im nachstehenden Beispiel können Sie erkennen, warum dies ein Problem ist.
Angenommen, eine Tabelle wird mit einem skriptgesteuerten Upload synchronisiert. Der Einfachheit halber wird angenommen, dass nur Einfügungen heraufgeladen werden. Die Tabelle enthält eine insert_time-Spalte, also einen Zeitstempel, der den Zeitpunkt angibt, zu dem eine Zeile eingefügt wurde.
Jeder Upload wird aufgebaut, indem alle festgeschriebenen Zeilen in der Tabelle ausgewählt werden, bei denen der Wert der insert_time-Spalte nach dem Zeitpunkt des letzten erfolgreichen Uploads und vor dem Zeitpunkt liegt, an dem Sie mit dem Aufbauen des aktuellen Uploads begonnen haben (also der Zeitpunkt, zu dem der Hook sp_hook_dbmlsync_set_upload_end_progress aufgerufen wurde). Angenommen, Folgendes tritt ein.
Zeit | |
---|---|
1:00:00 | Eine erfolgreiche Synchronisation wird vorgenommen. |
1:04:00 | Zeile R wird in die Tabelle eingefügt, aber nicht festgeschrieben. Die insert_time-Spalte für R ist auf 1:04:00 gesetzt. |
1:05:00 | Eine Synchronisation wird vorgenommen. Der Upload der Zeilen mit insert_time-Werten zwischen 1:00:00 und 1:05:00 wird vorgenommen. Der Upload der Zeile R wird nicht vorgenommen, weil die Zeile nicht festgeschrieben ist. Der Synchronisationsfortschritt wird auf 1:05:00 gesetzt. |
1:07:00 | Die um 1:04:00 eingefügte Zeile wird festgeschrieben. Die insert_time-Spalte für R bleibt auf 1:04:00 gesetzt. |
1:10:00 | Eine Synchronisation wird vorgenommen. Der Upload der Zeilen mit insert_time-Werten zwischen 1:05:00 und 1:10:00 wird vorgenommen. Der Upload der Zeile R wird nicht vorgenommen, weil ihr insert_time-Wert außerhalb des Bereichs liegt. Das heißt, die Zeile R wird nie übertragen. |
Grundsätzlich kann davon ausgegangen werden, dass ein Vorgang, der vor der Synchronisation eintritt und danach festgeschrieben wird, bei dieser Vorgehensweise verloren geht.
Die einfachste Art der Verarbeitung nicht festgeschriebener Transaktionen besteht darin, den Hook sp_hook_dbmlsync_set_upload_end_progress zu verwenden, um das Verarbeitungsende für jede Synchronisation auf den Startzeitpunkt der ältesten, nicht festgeschriebenen Transaktion auf den Zeitpunkt zu setzen, zu dem der Hook aufgerufen wird. Sie können diesen Zeitpunkt mit der Systemprozedur sa_transactions wie folgt festlegen:
SELECT min( start_time ) FROM sa_transactions() |
In diesem Fall müssen Ihre gespeicherten Upload-Prozeduren den Abschluss-Verarbeitungsfortschritt ignorieren, das im Hook sp_hook_dbmlsync_set_upload_end_progress mit sa_transactions kalkuliert und über die #hook_dict-Tabelle übergeben wurde. Die gespeicherten Prozeduren müssen einfach einen Upload aller festgeschriebenen Vorgänge vornehmen, die nach dem Start-Verarbeitsfortschritt eingetreten sind. Damit wird sichergestellt, dass der Download keine Zeilen mit Änderungen überschreibt, für die noch ein Upload durchgeführt werden muss. Außerdem wird damit gewährleistet, dass ein Upload von Vorgängen rechtzeitig erfolgt, auch wenn nicht festgeschriebene Transaktionen vorhanden sind.
Diese Lösung stellt sicher, dass keine Vorgänge verloren gehen. Allerdings kann es vorkommen, dass ein Upload einiger Vorgänge mehr als einmal erfolgt. Ihre serverseitigen Skripten müssen so geschrieben sein, dass sie Vorgänge verarbeiten, deren Upload mehr als einmal vorgenommen wird. Nachstehend sehen Sie ein Beispiel, in dem gezeigt wird, wie bei dieser Vorgehensweise der Upload einer Zeile mehr als einmal erfolgen kann.
Zeit | |
---|---|
1:00:00 | Eine erfolgreiche Synchronisation wird vorgenommen. |
2:00:00 | Zeile R1 wird eingefügt, aber nicht festgeschrieben. |
2:10:00 | Zeile R2 wird eingefügt und festgeschrieben. |
3:00:00 | Eine Synchronisation wird vorgenommen. Ein Upload der Vorgänge, die zwischen 1:00 und 3:00 eingetreten sind, wird vorgenommen. Ein Upload der Zeile R2 wird vorgenommen und der Verarbeitungsfortschritt wird auf 2:00 gesetzt, weil dies der Startzeitpunkt der ältesten, nicht festgeschriebenen Transaktion ist. |
4:00:00 | Zeile R1 wird festgeschrieben. |
5:00:00 | Eine Synchronisation wird vorgenommen. Vorgänge, die zwischen 2:00 und 5:00 aufgetreten sind, werden heraufgeladen und der Fortschritt wird auf 5:00 gesetzt. Der Upload enthält die Zeilen R1 und R2, da die Zeitstempel dieser Zeilen innerhalb des Upload-Zeitraums liegen. Daher wurde der Upload von R2 zweimal durchgeführt. |
Wenn Ihre konsolidierte Datenbank eine SQL Anywhere-Datenbank ist, können Sie redundante Uploads von Einfügevorgängen durch die Anweisung INSERT … ON EXISTING UPDATE in Ihrem upload_insert-Skript in der konsolidierten Datenbank verarbeiten.
Bei anderen konsolidierten Datenbanken können Sie eine ähnliche Programmlogik in einer gespeicherten Prozedur implementieren, die von Ihrem upload_insert-Skript aufgerufen wird. Schreiben Sie eine Prüfroutine, um zu verifizieren, ob eine Zeile mit dem Primärschlüssel der eingefügten Zeile bereits in der konsolidierten Datenbank existiert. Wenn die Zeile existiert, aktualisieren Sie sie, sonst fügen Sie die neue Zeile ein.
Redundante Uploads von Lösch- und Aktualisierungsvorgängen sind ein Problem, wenn Sie Konflikterkennung oder Konfliktbereinigungslogik auf der Serverseite eingerichtet haben. Wenn Sie Konflikterkennungs- und Konfliktlösungsskripten auf der Serverseite schreiben, müssen diese auch für die Verarbeitung redundanter Uploads ausgelegt sein.
Redundante Uploads von Löschvorgängen können wichtig werden, wenn Primärschlüsselwerte von der konsolidierten Datenbank wiederverwendet werden können. Es gibt die folgende Abfolge von Ereignissen:
Zeile R mit dem Primärschlüssel 100 wird in einer entfernten Datenbank eingefügt und ein Upload in die konsolidierte Datenbank erfolgt.
Zeile R wird in der entfernten Datenbank gelöscht und ein Upload des Löschvorgangs erfolgt.
Eine neue Zeile R’ mit dem Primärschlüssel 100 wird in die konsolidierte Datenbank eingefügt.
Der Upload des Löschvorgangs in Zeile R aus Schritt 2 aus der entfernten Datenbank wird nochmals durchgeführt. Dies kann dazu führen, dass R' aus der konsolidierten Datenbank fälschlicherweise gelöscht wird.
Kommentieren Sie diese Seite in DocCommentXchange. Senden Sie uns Feedback über diese Seite via E-Mail. |
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |