Datenkonflikte bei Transaktionen
DIese Seite beschreibt Inhalt, Serialisierbarkeit und Isolation von Transaktionsdaten. Transaktions-Codebeispiele finden Sie unter Transaktionen und Batch-Schreibvorgänge.
Transaktionen und Datenkonflikte
Um eine Transaktion erfolgreich durchzuführen ist es erforderlich, dass die von ihren Lesevorgängen abgerufenen Dokumente nicht von Vorgängen außerhalb der Transaktion verändert werden. Wenn ein anderer Vorgang versucht, eines der relevanten Dokumente zu ändern, wechseln diese Vorgänge in einen Datenkonflikt-Status mit der Transaktion.
- Datenkonflikt
- Wenn zwei oder mehr Vorgänge um die Verwaltung eines Dokument streiten. Beispiel: Eine Transaktion kann es erforderlich machen, dass ein Dokument unverändert bleibt, während ein gleichzeitiger Vorgang versucht, die Feldwerte des Dokuments zu aktualisieren.
Zur Lösung von Datenkonflikten verzögert Firestore einen der Vorgänge, oder läßt ihn fehlschlagen. Firestore-Clientbibliotheken wiederholen automatisch Transaktionen, die aufgrund von Datenkonflikten fehlschlagen. Nach einer begrenzten Anzahl Wiederholungen schlägt der Transaktionsvorgang fehl und gibt eine Fehlermeldung zurück:
ABORTED: Too much contention on these documents. Please try again.
Bei der Entscheidung, ob ein Vorgang fehlschlägt oder verzögert wird, hängt das Verhalten vom Typ der Clientbibliothek ab.
Die mobilen/Web-SDKs verwenden eine optimistische Gleichzeitigkeitserkennung.
Server-Clientbibliotheken verwenden eine pessimistische Gleichzeitigkeitserkennung.
Datenkonflikte in mobilen/Web-SDKs
Die mobilen/Web-SDKs (Apple-Plattformen, Android, Web, C++) nutzen eine optimistische Gleichzeitigkeitserkennung, um Datenkonflikte zu lösen.
- Optimistische Gleichzeitigkeitserkennung
- Geht von der Annahme aus, dass ein Datenkonflikt unwahrscheinlich oder eine Datenbanksperrung nicht effizient ist. Optimistische Transaktionen nutzen nie Datenbanksperren, um andere Vorgänge daran zu hindern, Daten zu ändern.
Mobile/Web-SDKs verwenden eine optimistische Gleichzeitigkeitserkennung, da sie oft in Umgebungen mit hoher Latenz und unzuverlässigen Netzwerkverbindungen ausgeführt werden. Das Sperren von Dokumenten in einer Umgebung mit hoher Latenz würde zu vielen Abbrüchen wegen Datenkonflikten führen.
Bei mobilen/Web-SDKs erfassen Transaktionen alle Dokumente, die Sie in der Transaktion lesen. Die Transaktion schließt Schreibvorgänge nur ab, wenn keines dieser Dokumente während der Ausführung der Transaktion geändert wurde. Wurde ein Dokument geändert, so wiederholt der Transaktions-Handler die Transaktion. Erhält die Transaktion nach einigen Wiederholungsversuchen kein sauberes Ergebnis, so schlägt die Transaktion aufgrund eines Datenkonflikts fehl.
Datenkonflikte in Server-Clientbibliotheken
Server-Clientbibliotheken (C#, Go, Java, Node.js, PHP, Python, Ruby) verwenden eine pessimistische Gleichzeitigkeitserkennung zur Lösung von Datenkonflikten.
- Pessimistische Gleichzeitigkeitserkennung
- Geht von der Annahme aus, dass ein Datenkonflikt wahrscheinlich ist. Pessimistische Transaktionen verwenden Datenbanksperren, um zu verhindern, dass andere Vorgänge Daten ändern.
Server-Clientbibliotheken nutzen eine pessimistische Gleichzeitigkeitserkennung, da sie von einer niedrigen Latenz und einer zuverlässigen Verbindung zur Datenbank ausgehen.
In Server-Clientbibliotheken werden Transaktionen für die gelesenen Dokumente gesperrt. Die Sperre einer Transaktion für ein Dokument hindert andere Transaktionen, Batch-Schreibvorgänge und nicht transaktionale Schreibvorgänge daran, Änderungen am relevanten Dokument vorzunehmen. Transaktionen geben ihre Dokumentsperren zur Zeit des Commits frei. Außerdem werden Sperren freigegeben, wenn das Zeitlimit überschritten wird oder wenn die Transaktion aus irgendeinem Grund fehlschlägt.
Sperrt eine Transaktion ein Dokument, so müssen andere Schreibvorgänge warten, bis die Transaktion ihre Sperre aufgehoben hat. Transaktionen erhalten Sperren in chronologischer Reihenfolge.
Serialisierbare Isolation
Datenkonflikte zwischen Transaktionen stehen eng mit Datenbank-Isolationsebenen zusammen. Die Isolationsebene einer Datenbank beschreibt, wie gut das System Konflikte zwischen gleichzeitigen Vorgängen verarbeitet. Dieser Konflikt stammt aus den folgenden Datenbankanforderungen:
- Transaktionen erfordern präzise und konsistente Daten.
- Zur effizienten Ressourcennutzung werden Datenbankvorgänge gleichzeitig ausgeführt.
In Systemen mit geringer Isolationsebene kann ein Lesevorgang innerhalb einer Transaktion nicht korrekte Daten aufgrund von nicht übergebenen Änderungen während eines gleichzeitigen Vorgangs lesen.
Die serialisierbare Isolation stellt die höchste Isolationsebene dar. Eine serialisierbare Isolation meint Folgendes:
- Sie dürfen davon ausgehen, dass in der Datenbank Transaktionen der Reihe nach ausgeführt werden.
- Transaktionen werden nicht vorgenommene Änderungen bei gleichzeitigen Vorgängen beeinträchtigt.
Diese Garantie muss auch dann gelten, wenn die Datenbank mehrere Transaktionen parallel ausführt. Die Datenbank muss eine Gleichzeitigkeitserkennung implementieren, um Konflikte zu lösen, die diese Garantie in Frage stellen.
Firestore garantiert eine serialisierbare Isolation von Transaktionen. Transaktionen in Firestore werden serialisiert und nach Commit-Zeit isoliert.
Serialisierbare Isolation nach Commit-Zeit
Firestore weist jeder Transaktion eine Commit-Zeit zu, die einen bestimmten Zeitpunkt darstellt. Wenn Firestore die Änderungen einer Transaktion per Commit an die Datenbank übergibt, können Sie davon ausgehen, dass alle Lese- und Schreibvorgänge innerhalb der Transaktion genau zur Zeit des Commits erfolgen.
Die tatsächliche Ausführung einer Transaktion erfordert eine gewisse Zeit. Die Ausführung einer Transaktion beginnt vor der Commit-Zeit. Die Ausführungen mehrerer Vorgänge können sich überschneiden. Firestore bewahrt die serialisierbare Isolation bei und garantiert Folgendes:
- Firestore übernimmt die Transaktionen in der Reihenfolge ihrer Commit-Zeit.
- Firestore isoliert Transaktionen von gleichzeitigen Vorgängen unter Einsatz einer späteren Commit-Zeit.
Im Falle eines Datenkonflikts zwischen gleichzeitig ausgeführten Vorgängen verwendet Firestore optimistische und pessimistische Gleichzeitigkeitserkennungen, um Konflikte zu lösen.
Isolation innerhalb einer Transaktion
Die Transaktionsisolation gilt auch für Schreibvorgänge innerhalb einer Transaktion. Abfragen und Lesevorgänge innerhalb einer Transaktion sehen die Ergebnisse vorheriger Schreibvorgänge innerhalb dieser Transaktion nicht. Auch wenn Sie ein Dokument innerhalb einer Transaktion ändern oder löschen, geben alle Dokumente in dieser Transaktion die Version des Dokuments zum Commit-Zeitpunkt vor den Schreibvorgängen der Transaktion zurück. Lesevorgänge geben nichts zurück, wenn das Dokument zu diesem Zeitpunkt nicht existierte.
Probleme mit Datenkonflikten
Weitere Informationen zu Datenkonflikten und deren Behebung finden Sie auf der Fehlerbehebungsseite.