serializowalność i izolacja transakcji;

Na tej stronie opisujemy spory 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 konkurencją o dane, 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 sterowanie współbieżnością zakłada, że wystąpi konflikt danych. 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, które odczytują. Blokada dokumentu przez transakcję uniemożliwia innym transakcjom, wsadowym operacjom zapisu i operacjom zapisu bez transakcji zmianę tego dokumentu. Transakcja zwalnia blokady dokumentów w momencie zatwierdzenia. Zwalnia też blokady, jeśli przekroczy limit czasu lub z jakiegokolwiek powodu zakończy się niepowodzeniem.

    Gdy transakcja blokuje 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 konflikt danych jest mało prawdopodobny lub że utrzymywanie blokad bazy danych nie jest efektywne. 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 jej ramach. Operacje zapisu są wykonywane tylko wtedy, gdy żaden z tych dokumentów nie został zmieniony podczas wykonywania transakcji. Jeśli jakikolwiek dokument został zmieniony, moduł obsługi transakcji ponawia transakcję. 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 przypadku wersji Standard domyślna wartość to PESSIMISTIC, a w przypadku wersji Enterprise – OPTIMISTIC. Działanie zależy jednak też 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 przetwarzanie.
  • Biblioteki klienta serwera korzystają z ustawień bazy danych dotyczących kontroli współbieżności.

Wyświetlanie trybu współbieżności

Aby wyświetlić tryb współbieżności po stronie serwera bazy danych, uruchom polecenie gcloud firestore databases describe:

gcloud firestore databases describe \
  --project=PROJECT_ID \
  --database=DATABASE_ID

Zmiana trybu współbieżności

Aby zmienić tryb współbieżności po stronie serwera bazy danych, uruchom polecenie gcloud firestore databases update:

gcloud firestore databases update \
  --project=PROJECT_ID \
  --database=DATABASE_ID \
  --concurrency-mode=CONCURRENCY_MODE

gdzie:

  • CONCURRENCY_MODE to PESSIMISTIC lub OPTIMISTIC.
  • PROJECT_ID to identyfikator Twojego projektu Google Cloud.
  • DATABASE_ID to identyfikator bazy danych Cloud Firestore.
optymistyczne lub pesymistyczne mechanizmy kontroli współbieżności.

Konflikt danych w mobilnych i internetowych pakietach SDK

Pakiety SDK na urządzenia mobilne i do internetu emulują transakcje z optymistycznym współbieżnym dostępem, używając warunków wstępnych zapisu w wersjach dokumentów. Ta 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 wbudowanych transakcji, więc nawet jeśli tryb współbieżności bazy danych jest skonfigurowany na PESSIMISTIC, klienci mobilni nadal zachowują się optymistycznie.

Zestawy SDK na urządzenia mobilne i do internetu korzystają z optymistycznej kontroli współbieżności, ponieważ mogą działać w środowiskach o dużym opóźnieniu 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 konfliktami danych.

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 standardowa korzysta z pesymistycznych mechanizmów kontroli współbieżności i zakłada małe opóźnienie oraz niezawodne połączenie z bazą danych.

Izolacja serializowalna

Konflikt danych między transakcjami jest ściśle powiązany z poziomami izolacji bazy danych. Poziom izolacji bazy danych określa, jak dobrze 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 z możliwością serializacji to najwyższy poziom izolacji. Poziom izolacji Serializable oznacza, że:

  • Możesz założyć, że baza danych wykonuje transakcje seryjnie.
  • Transakcje nie są objęte niezatwierdzonymi 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 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 zachowuje izolację z możliwością serializacji 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 konfliktu danych między operacjami wykonywanymi jednocześnie usługa Cloud Firestore używa optymistycznej i pesymistycznej kontroli równoczesności, aby rozwiązać konflikt.

Izolacja w ramach transakcji

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

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.