Na tej stronie opisujemy rywalizację o dane transakcyjne, serializowalność i izolację. Przykłady kodu transakcji znajdziesz w artykule Transakcje i zapisywanie zbiorcze.
Transakcje i konflikty danych
Aby transakcja zakończyła się powodzeniem, dokumenty pobrane przez operacje odczytu muszą pozostać niezmienione przez operacje spoza transakcji. Jeśli inna operacja spróbuje zmienić jeden z tych dokumentów, wejdzie w stan konfliktu danych z transakcją.
- Konflikt danych
- Gdy co najmniej 2 operacje konkurują o kontrolę nad tym samym dokumentem. Na przykład jedna transakcja może wymagać, aby dokument pozostał spójny, podczas gdy równoczesna operacja próbuje zaktualizować wartości pól tego dokumentu.
Cloud Firestore rozwiązuje problem z konfliktem danych, opóźniając lub przerywając jedną z operacji. Cloud FirestoreBiblioteki klienta automatycznie ponawiają transakcje, które nie powiodły się z powodu konfliktu danych. Po skończonej liczbie ponownych prób operacja transakcji kończy się niepowodzeniem i zwraca komunikat o błędzie:
ABORTED: Too much contention on these documents. Please try again.
Decyzja o tym, która operacja ma się nie powieść lub zostać opóźniona, zależy od typu mechanizmów kontroli współbieżności.
Ustawienia równoczesności
Tryb współbieżności jest konfigurowalną opcją bazy danych. Cloud Firestore obsługuje te tryby współbieżności:
PESSIMISTIC: Pesymistyczne mechanizmy kontroli współbieżności zakładają, że konflikt danych jest prawdopodobny. Transakcje pesymistyczne używają blokad bazy danych, aby uniemożliwić innym operacjom modyfikowanie danych.W przypadku pesymistycznej kontroli współbieżności transakcje blokują dokumenty, z których odczytują dane. Blokada transakcji w dokumencie uniemożliwia innym transakcjom, zapisanym zbiorczo operacjom zapisu i operacjom zapisu bez transakcji zmianę tego dokumentu. Transakcja zwalnia blokady dokumentu w momencie zatwierdzenia. Zwalnia też blokady, jeśli upłynie limit czasu lub wystąpi błąd z jakiegokolwiek powodu.
Gdy transakcja zablokuje dokument, inne operacje zapisu muszą poczekać, aż transakcja zwolni blokadę. Transakcje uzyskują blokady w kolejności chronologicznej.
OPTIMISTIC: Optymistyczne sterowanie współbieżnością zakłada, że rywalizacja o dane jest mało prawdopodobna lub że utrzymywanie blokad bazy danych jest nieefektywne. Transakcje optymistyczne nie używają blokad bazy danych, aby uniemożliwić innym operacjom zmianę danych.W przypadku optymistycznej kontroli współbieżności transakcja śledzi wszystkie dokumenty odczytane w ramach transakcji. Transakcja kończy operacje zapisu tylko wtedy, gdy żaden z tych dokumentów nie ulegnie zmianie podczas jej wykonywania. Jeśli jakikolwiek dokument uległ zmianie, moduł obsługi transakcji ponawia próbę transakcji. Jeśli po kilku próbach transakcja nie może uzyskać czystego wyniku, kończy się niepowodzeniem z powodu konfliktu danych.
Domyślne ustawienia trybu równoczesności
W wersji standardowej wartość domyślna to PESSIMISTIC. Wartość domyślna w wersji Enterprise to OPTIMISTIC. Zachowanie zależy jednak również od typu biblioteki klienta:
Pakiety SDK na urządzenia mobilne i do internetu korzystają z optymistycznej kontroli współbieżności. Pakiety SDK na urządzenia mobilne i do internetu działają niezależnie od tego ustawienia, ponieważ zawsze emulują optymistyczne współbieżne wykonywanie.
Biblioteki klienta serwera korzystają z ustawień bazy danych dotyczących kontroli współbieżności.
Konflikt danych w mobilnych i internetowych pakietach SDK
Pakiety SDK na urządzenia mobilne i do internetu emulują transakcje optymistycznego współbieżnego dostępu, używając warunków wstępnych zapisu w wersjach dokumentów. Emulacja występuje niezależnie od ustawienia trybu współbieżności bazy danych. Pakiety SDK na urządzenia mobilne i do internetu nie korzystają z funkcji wbudowanych transakcji, więc nawet jeśli tryb współbieżności bazy danych jest skonfigurowany na PESSIMISTIC, klienci mobilni nadal działają optymistycznie.
Pakiety SDK na urządzenia mobilne i do internetu korzystają z optymistycznej kontroli współbieżności, ponieważ mogą działać w środowiskach o dużych opóźnieniach i niestabilnym połączeniu sieciowym. Blokowanie dokumentów w środowisku o dużym opóźnieniu powodowałoby zbyt wiele błędów związanych z konkurencją o dane.
Konflikty danych w bibliotekach klienta serwera
Biblioteki klienta serwera (C#, Go, Java, Node.js, PHP, Python, Ruby) korzystają z wbudowanych transakcji. W przypadku tych transakcji używane jest ustawienie trybu współbieżności na poziomie bazy danych, a wartość domyślna zależy od wersji:
Wersja Enterprise domyślnie używa optymistycznej kontroli współbieżności, aby obsługiwać operacje skanujące całe kolekcje. Optymistyczne sterowanie współbieżnością pomaga unikać operacji skanowania, które blokują dużą liczbę dokumentów.
Wersja Standard używa pesymistycznych mechanizmów kontroli współbieżności i zakłada małe opóźnienie oraz niezawodne połączenie z bazą danych.
Izolacja z możliwością serializacji
Konflikt danych między transakcjami jest ściśle powiązany z poziomami izolacji bazy danych. Poziom izolacji bazy danych określa, jak system radzi sobie z konfliktami między operacjami wykonywanymi jednocześnie. Konflikt wynika z tych wymagań bazy danych:
- Transakcje wymagają dokładnych i spójnych danych.
- Aby efektywnie wykorzystywać zasoby, bazy danych wykonują operacje równolegle.
W systemach o niskim poziomie izolacji operacja odczytu w ramach transakcji może odczytywać niedokładne dane z niezatwierdzonych zmian w równoczesnej operacji.
Izolacja szeregowa to najwyższy poziom izolacji. Poziom izolacji Serializable oznacza, że:
- Możesz założyć, że baza danych wykonuje transakcje w seriach.
- Transakcje nie są objęte niezapisywanymi zmianami w przypadku równoczesnych operacji.
Ta gwarancja musi być zachowana nawet wtedy, gdy baza danych wykonuje równolegle wiele transakcji. Baza danych musi implementować mechanizmy kontroli współbieżności, aby rozwiązywać konflikty, które mogłyby naruszyć tę gwarancję.
Cloud Firestore gwarantuje serializowalną izolację transakcji. Transakcje w Cloud Firestore są serializowane i izolowane według czasu zatwierdzenia.
Izolacja serializowalna według czasu zatwierdzenia
Cloud Firestore przypisuje każdej transakcji czas zatwierdzenia, który reprezentuje pojedynczy moment w czasie. Gdy Cloud Firestore zatwierdza zmiany transakcji w bazie danych, możesz założyć, że wszystkie odczyty i zapisy w ramach transakcji odbywają się dokładnie w momencie zatwierdzenia.
Rzeczywiste wykonanie transakcji wymaga pewnego czasu. Wykonanie transakcji rozpoczyna się przed czasem zatwierdzenia, a wykonanie wielu operacji może się nakładać. Cloud Firestore zapewnia izolację z możliwością serializacji i gwarantuje, że:
- Cloud Firestore zatwierdza transakcje w kolejności zgodnej z czasem zatwierdzenia.
- Cloud Firestore izoluje transakcje od równoczesnych operacji z późniejszym czasem zatwierdzenia.
W przypadku konfliktu danych między operacjami wykonywanymi jednocześnie usługa Cloud Firestore używa optymistycznej i pesymistycznej kontroli współbieżności, aby rozwiązać konflikt.
Izolacja w ramach transakcji
Izolacja transakcji dotyczy też operacji zapisu w ramach transakcji. Zapytania i odczyty w transakcji nie widzą wyników poprzednich zapisów w tej transakcji. Nawet jeśli zmodyfikujesz lub usuniesz dokument w ramach transakcji, wszystkie odczyty dokumentu w tej transakcji zwrócą wersję dokumentu w momencie zatwierdzenia, czyli przed operacjami zapisu transakcji. Operacje odczytu nie zwracają niczego, jeśli dokument nie istniał w danym momencie.
Problemy z konkurencją o dane
Więcej informacji o konfliktach danych i sposobach ich rozwiązywania znajdziesz na stronie dotyczącej rozwiązywania problemów.