serializowalność i izolacja transakcji;

Na tej stronie opisujemy rywalizację o dane transakcyjne, serializowalność i izolację. Przykłady kodu transakcji znajdziesz w sekcji Transakcje i zapisywanie zbiorcze.

Transakcje i rywalizacja o dane

Aby transakcja się powiodła, dokumenty pobrane przez operacje odczytu w jej ramach muszą pozostać niezmienione przez operacje spoza transakcji. Jeśli inna operacja spróbuje zmienić jeden z tych dokumentów, wejdzie w stan rywalizacji o dane z transakcją.

Rywalizacja o dane
Gdy co najmniej 2 operacje rywalizują 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 rywalizację o dane, opóźniając lub przerywając jedną z operacji. Biblioteki klienta Cloud Firestore automatycznie ponawiają transakcje, które nie powiodły się z powodu rywalizacji o dane. Po skończonej liczbie ponownych prób operacja transakcji nie powiedzie się i zwróci 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 równoczesności.

Mechanizmy kontroli równoczesności

Tryb równoczesności to konfigurowalna opcja bazy danych. Cloud Firestore obsługuje te tryby równoczesności:

  • PESSIMISTIC: mechanizmy kontroli równoczesności pesymistycznej zakładają, że rywalizacja o dane jest prawdopodobna. Transakcje pesymistyczne używają blokad bazy danych, aby uniemożliwić innym operacjom modyfikowanie danych.

    W przypadku mechanizmów kontroli równoczesności pesymistycznej transakcje blokują dokumenty, które odczytują. Blokada dokumentu przez transakcję uniemożliwia innym transakcjom, zapisom zbiorczym i zapisom nietransakcyjnym zmianę tego dokumentu. Transakcja zwalnia blokady dokumentów w momencie zatwierdzenia. Zwalnia też blokady, jeśli upłynie limit czasu lub transakcja nie powiedzie się z jakiegokolwiek powodu.

    Gdy transakcja blokuje dokument, inne operacje zapisu muszą poczekać, aż transakcja zwolni blokadę. Transakcje uzyskują blokady w kolejności chronologicznej.

  • OPTIMISTIC: mechanizmy kontroli równoczesności optymistycznej zakładają, ż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 mechanizmów kontroli równoczesności optymistycznej transakcja śledzi wszystkie dokumenty odczytane w jej ramach. Transakcja kończy operacje zapisu tylko wtedy, gdy żaden z tych dokumentów nie został zmieniony podczas wykonywania transakcji. Jeśli jakikolwiek dokument został zmieniony, procedura obsługi transakcji ponawia transakcję. Jeśli po kilku ponownych próbach transakcja nie może uzyskać czystego wyniku, nie powiedzie się z powodu rywalizacji o dane.

Domyślne ustawienia trybu równoczesności

W przypadku wersji Standard wartość domyślna to PESSIMISTIC. W przypadku wersji Enterprise wartość domyślna to OPTIMISTIC. Zachowanie zależy jednak też od typu biblioteki klienta:

  • Pakiety SDK na urządzenia mobilne i do internetu używają mechanizmów kontroli równoczesności optymistycznej. Pakiety SDK na urządzenia mobilne i do internetu działają niezależnie od tego ustawienia, ponieważ zawsze emulują równoczesność optymistyczną.

  • Biblioteki klienta serwera używają mechanizmów kontroli równoczesności ustawionych w bazie danych.

Rywalizacja o dane w pakietach SDK na urządzenia mobilne i do internetu

Pakiety SDK na urządzenia mobilne i do internetu emulują transakcje równoczesności optymistycznej za pomocą warunków wstępnych zapisu w wersjach dokumentów. Ta emulacja występuje niezależnie od ustawienia trybu równoczesności bazy danych. Pakiety SDK na urządzenia mobilne i do internetu nie używają wbudowanej funkcji transakcji, więc nawet jeśli tryb równoczesności bazy danych jest skonfigurowany jako PESSIMISTIC, klienci mobilni nadal zachowują się optymistycznie.

Pakiety SDK na urządzenia mobilne i do internetu używają mechanizmów kontroli równoczesności optymistycznej, ponieważ mogą działać w środowiskach z dużym opóźnieniem i zawodnym połączeniem sieciowym. Blokowanie dokumentów w środowisku z dużym opóźnieniem spowodowałoby zbyt wiele błędów rywalizacji o dane.

Rywalizacja o dane w bibliotekach klienta serwera

Biblioteki klienta serwera (C#, Go, Java, Node.js, PHP, Python, Ruby) use the built-in transactions feature. Te transakcje używają ustawienia trybu równoczesności na poziomie bazy danych, a wartość domyślna zależy od wersji:

  • Wersja Enterprise domyślnie używa mechanizmów kontroli równoczesności optymistycznej, aby obsługiwać operacje skanujące całe kolekcje. Mechanizmy kontroli równoczesności optymistycznej pomagają unikać operacji skanowania, które blokują dużą liczbę dokumentów.

  • Wersja Standard używa mechanizmów kontroli równoczesności pesymistycznej i zakłada małe opóźnienie oraz niezawodne połączenie z bazą danych.

Izolacja serializowalna

Rywalizacja o dane między transakcjami jest ściśle związana z poziomami izolacji bazy danych. Poziom izolacji bazy danych opisuje, jak dobrze system radzi sobie z konfliktami między równoczesnymi operacjami. Konflikt wynika z tych wymagań bazy danych:

  • Transakcje wymagają dokładnych i spójnych danych.
  • Aby efektywnie wykorzystywać zasoby, bazy danych wykonują operacje równocześnie.

W systemach o niskim poziomie izolacji operacja odczytu w ramach transakcji może odczytać niedokładne dane z niezatwierdzonych zmian w równoczesnej operacji.

Izolacja serializowalna definiuje najwyższy poziom izolacji. Izolacja serializowalna oznacza, że:

  • Możesz założyć, że baza danych wykonuje transakcje szeregowo.
  • Transakcje nie są narażone na niezatwierdzone zmiany w równoczesnych operacjach.

Ta gwarancja musi być spełniona nawet wtedy, gdy baza danych wykonuje równolegle wiele transakcji. Baza danych musi implementować mechanizmy kontroli równoczesności, aby rozwiązywać konflikty, które mogłyby naruszyć tę gwarancję.

Cloud Firestore gwarantuje izolację serializowalną 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 punkt 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 czasie 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 utrzymuje izolację serializowalną i gwarantuje, że:

  • Cloud Firestore zatwierdza transakcje w kolejności według czasu zatwierdzenia.
  • Cloud Firestore izoluje transakcje od równoczesnych operacji z późniejszym czasem zatwierdzenia.

W przypadku rywalizacji o dane między równoczesnymi operacjami, Cloud Firestore używa mechanizmów kontroli równoczesności optymistycznej i pesymistycznej, aby rozwiązać rywalizację.

Izolacja w ramach transakcji

Izolacja transakcji dotyczy też operacji zapisu w ramach transakcji. Zapytania i odczyty w ramach transakcji nie widzą wyników poprzednich zapisów w tej transakcji. Nawet jeśli zmodyfikujesz lub usuniesz dokument w ramach transakcji, wszystkie odczyty dokumentów w tej transakcji zwrócą wersję dokumentu w czasie zatwierdzenia, czyli przed operacjami zapisu transakcji. Operacje odczytu nie zwracają niczego, jeśli dokument nie istniał w tym czasie.

Problemy z rywalizacją o dane

Więcej informacji o rywalizacji o dane i sposobach jej rozwiązywania znajdziesz na stronie rozwiązywania problemów.