Questa pagina descrive la contesa dei dati transazionali, la serializzabilità e l'isolamento. Per esempi di codice delle transazioni, consulta invece Transazioni e scritture in batch.
Transazioni e conflitto di dati
Affinché una transazione vada a buon fine, i documenti recuperati dalle relative operazioni di lettura non devono essere modificati da operazioni esterne alla transazione. Se un'altra operazione tenta di modificare uno di questi documenti, l'operazione entra in uno stato di conflitto di dati con la transazione.
- Contesa dei dati
- Quando due o più operazioni competono per controllare lo stesso documento. Ad esempio, una transazione potrebbe richiedere che un documento rimanga coerente mentre un'operazione simultanea tenta di aggiornare i valori dei campi del documento.
Cloud Firestore risolve i conflitti di dati ritardando o non riuscendo a eseguire una delle operazioni. Le librerie client di Cloud Firestore riprovano automaticamente le transazioni che non vanno a buon fine a causa di conflitti di dati. Dopo un numero finito di nuovi tentativi, l'operazione di transazione non va a buon fine e restituisce un messaggio di errore:
ABORTED: Too much contention on these documents. Please try again.
Quando si decide quale operazione non riuscire o ritardare, il comportamento dipende dal tipo di controlli della concorrenza.
Controlli della concorrenza
La modalità di contemporaneità è un'opzione di database configurabile. Cloud Firestore supporta le seguenti modalità di contemporaneità:
PESSIMISTIC: i controlli della concorrenza pessimistici presuppongono che la contesa dei dati sia probabile. Le transazioni pessimistiche utilizzano i blocchi del database per impedire ad altre operazioni di modificare i dati.Con i controlli della concorrenza pessimistici, le transazioni applicano blocchi ai documenti che leggono. Il blocco di un documento da parte di una transazione impedisce ad altre transazioni, scritture in batch e scritture non transazionali di modificare il documento. Una transazione rilascia i blocchi dei documenti al momento del commit. Inoltre, rilascia i blocchi se si verifica un timeout o un errore per qualsiasi motivo.
Quando una transazione blocca un documento, le altre operazioni di scrittura devono attendere che la transazione rilasci il blocco. Le transazioni acquisiscono i blocchi in ordine cronologico.
OPTIMISTIC: i controlli della concorrenza ottimistica presuppongono che la contesa dei dati non sia probabile o che non sia efficiente mantenere i blocchi del database. Le transazioni ottimistiche non utilizzano i blocchi del database per impedire ad altre operazioni di modificare i datiCon i controlli della concorrenza ottimistica, una transazione tiene traccia di tutti i documenti che leggi al suo interno. La transazione completa le operazioni di scrittura solo se nessuno di questi documenti è stato modificato durante l'esecuzione della transazione. Se un documento è stato modificato, il gestore delle transazioni riprova a eseguire la transazione. Se la transazione non riesce a ottenere un risultato pulito dopo alcuni tentativi, non va a buon fine a causa della contesa dei dati.
Valori predefiniti della modalità di concorrenza
Il valore predefinito per la versione Standard è PESSIMISTIC. Il valore predefinito per la versione Enterprise è OPTIMISTIC. Tuttavia, il comportamento dipende anche dal tipo di libreria client:
- Gli SDK web / mobile utilizzano controlli della concorrenza ottimistici. Gli SDK web e mobile si comportano in modo indipendente da questa impostazione, poiché emulano sempre la concorrenza ottimistica.
- Le librerie client del server utilizzano i controlli della concorrenza dell'impostazione del database.
Modalità di contemporaneità della visualizzazione
Esegui il comando gcloud firestore databases describe per visualizzare la modalità di contemporaneità lato server del database:
gcloud firestore databases describe \
--project=PROJECT_ID \
--database=DATABASE_ID
Cambia modalità di contemporaneità
Esegui il comando gcloud firestore databases update per modificare la modalità di contemporaneità lato server del database:
gcloud firestore databases update \
--project=PROJECT_ID \
--database=DATABASE_ID \
--concurrency-mode=CONCURRENCY_MODE
dove:
- CONCURRENCY_MODE è
PESSIMISTICoOPTIMISTIC. - PROJECT_ID è l'ID del tuo progetto Google Cloud.
- DATABASE_ID è l'ID del tuo database Cloud Firestore.
Concorrenza dei dati negli SDK web/per dispositivi mobili
Gli SDK web e per dispositivi mobili emulano le transazioni di contemporaneità ottimistica utilizzando le precondizioni di scrittura sulle versioni dei documenti. Questa emulazione avviene indipendentemente dall'impostazione della modalità di contemporaneità del database. Gli SDK web e per dispositivi mobili non utilizzano la funzionalità delle transazioni integrate, pertanto, anche se la modalità di contemporaneità del database è configurata per PESSIMISTIC, i client mobile continuano a comportarsi in modo ottimistico.
Gli SDK web/mobile utilizzano controlli della concorrenza ottimistici, perché possono operare in ambienti con latenza elevata e una connessione di rete non affidabile. Il blocco dei documenti in un ambiente ad alta latenza causerebbe troppi errori di conflitto dei dati.
Concorrenza dei dati nelle librerie client del server
Le librerie client server (C#, Go, Java, Node.js, PHP, Python, Ruby) utilizzano la funzionalità delle transazioni integrate. Queste transazioni utilizzano l'impostazione della modalità di contemporaneità a livello di database e l'impostazione predefinita dipende dalla versione:
La versione Enterprise utilizza per impostazione predefinita i controlli della concorrenza ottimistica per supportare le operazioni che eseguono la scansione di intere raccolte. I controlli della concorrenza ottimistica aiutano a evitare operazioni di scansione che bloccano un numero elevato di documenti.
La versione Standard utilizza controlli della concorrenza pessimistici e presuppone una bassa latenza e una connessione affidabile al database.
Isolamento serializzabile
La contesa dei dati tra le transazioni è strettamente correlata ai livelli di isolamento del database. Il livello di isolamento di un database descrive l'efficacia con cui il sistema gestisce i conflitti tra operazioni simultanee. Il conflitto deriva dai seguenti requisiti del database:
- Le transazioni richiedono dati accurati e coerenti.
- Per utilizzare le risorse in modo efficiente, i database eseguono le operazioni contemporaneamente.
Nei sistemi con un livello di isolamento basso, un'operazione di lettura all'interno di una transazione potrebbe leggere dati imprecisi da modifiche non sottoposte a commit in un'operazione concorrente.
L'isolamento serializzabile definisce il livello di isolamento più elevato. L'isolamento serializzabile significa che:
- Puoi presumere che il database esegua le transazioni in serie.
- Le transazioni non sono interessate dalle modifiche di cui non è stato eseguito il commit nelle operazioni simultanee.
Questa garanzia deve essere valida anche quando il database esegue più transazioni in parallelo. Il database deve implementare controlli della concorrenza per risolvere i conflitti che violerebbero questa garanzia.
Cloud Firestore garantisce l'isolamento serializzabile delle transazioni. Le transazioni in Cloud Firestore vengono serializzate e isolate in base all'ora di commit.
Isolamento serializzabile in base all'ora di commit
Cloud Firestore assegna a ogni transazione un tempo di commit che rappresenta un singolo momento nel tempo. Quando Cloud Firestore esegue il commit delle modifiche di una transazione nel database, puoi presumere che tutte le letture e le scritture all'interno della transazione avvengano esattamente al momento del commit.
L'esecuzione effettiva di una transazione richiede un certo periodo di tempo. L'esecuzione di una transazione inizia prima dell'ora di commit e l'esecuzione di più operazioni potrebbe sovrapporsi. Cloud Firestore supporta l'isolamento serializzabile e garantisce che:
- Cloud Firestore esegue il commit delle transazioni in ordine di tempo di commit.
- Cloud Firestore isola le transazioni dalle operazioni simultanee con un tempo di commit successivo.
In caso di conflitto di dati tra operazioni simultanee, Cloud Firestore utilizza controlli della concorrenza ottimistici e pessimistici per risolvere il conflitto.
Isolamento all'interno di una transazione
L'isolamento delle transazioni si applica anche alle operazioni di scrittura all'interno di una transazione. Le query e le letture all'interno di una transazione non vedono i risultati delle scritture precedenti all'interno della transazione. Anche se modifichi o elimini un documento all'interno di una transazione, tutte le letture dei documenti in quella transazione restituiscono la versione del documento al momento del commit, prima delle operazioni di scrittura della transazione. Le operazioni di lettura non restituiscono nulla se il documento non esisteva in quel momento.
Problemi di conflitto di dati
Per saperne di più sui conflitti di dati e su come risolverli, consulta la pagina di risoluzione dei problemi.