Serializzazione e isolamento delle transazioni

In questa pagina vengono descritti l'isolamento, la serializzazione e l'isolamento dei dati. Per esempi di transazioni, consulta la sezione Transazioni e scritture batch.

Transazioni e contenzione dei dati

Affinché una transazione vada a buon fine, i documenti recuperati dalle sue operazioni di lettura devono rimanere non modificati da operazioni al di fuori della transazione. Se un'altra operazione tenta di modificare uno di questi documenti, tale operazione entra in uno stato di contenzione dei dati con la transazione.

Contenzione 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.

Firestore risolve la contenzione dei dati ritardando o eseguendo il fallimento di una delle operazioni. Le librerie client di Firestore ritendono automaticamente le transazioni non riuscite a causa di una contese di dati. Dopo un certo numero di nuovi tentativi, l'operazione della transazione non riesce e restituisce un messaggio di errore:

ABORTED: Too much contention on these documents. Please try again.

Per decidere quale operazione eseguire o meno in ritardo, il comportamento dipende dal tipo di libreria client.

  • Gli SDK per dispositivi mobili/web utilizzano controlli simultanei ottimistici.

  • Le librerie client del server utilizzano controlli di contemporaneità pessimistici.

Contenzione dei dati negli SDK per dispositivi mobili/web

Gli SDK per dispositivi mobili/web (piattaforme Apple, Android, Web, C++) utilizzano controlli ottimizzati della contemporaneità per risolvere la congestione dei dati.

Controlli di contemporaneità ottimali
Sulla base del presupposto che è improbabile che la contenzione dei dati o il blocco dei database non siano efficaci. Le transazioni ottimali non utilizzano i blocchi dei database per impedire altre operazioni di modificare i dati.

Gli SDK per dispositivi mobili/web utilizzano controlli di contemporaneità ottimistici, perché possono funzionare in ambienti con alta latenza e connessione di rete inaffidabile. Il blocco dei documenti in un ambiente ad alta latenza causerebbe troppi errori di contenzione dei dati.

Negli SDK per dispositivi mobili/web, una transazione tiene traccia di tutti i documenti letti all'interno della transazione. La transazione viene completata solo se nessuno di questi documenti è cambiato durante l'esecuzione. Se un documento ha subito modifiche, il gestore delle transazioni proverà a rieseguire la transazione. Se dopo una serie di nuovi tentativi la transazione non riesce a ottenere un risultato positivo, la transazione non va a buon fine a causa della contenzione dei dati.

Contenzione dei dati nelle librerie client del server

Le librerie client del server (C#, Go, Java, Node.js, PHP, Python, Ruby) utilizzano i controlli pessimistici della risoluzione dei problemi relativi ai dati.

Controlli di contemporaneità pessimistici
Sulla base della supposizione che la contenzione dei dati sia probabile. Le transazioni pessistiche utilizzano i blocchi del database per impedire ad altre operazioni di modificare i dati.

Le librerie client del server utilizzano controlli di contemporaneità pessimistici, perché assumono bassa latenza e una connessione affidabile al database.

Nelle librerie client del server, le transazioni applicano blocchi ai documenti letti. Il blocco delle transazioni su un documento impedisce ad altre transazioni, scritture batch e scritture non transazionali di modificare tale documento. Una transazione di blocco consente di rilasciare i blocchi dei documenti al momento del commit. Inoltre, rilascia i blocchi se scade o non funziona 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.

Isolamento serializzabile

La connotazione dei dati tra le transazioni è strettamente correlata ai livelli di isolamento dei database. Il livello di isolamento di un database descrive il modo in cui il sistema gestisce i conflitti tra le operazioni simultanee. I conflitti derivano dai seguenti requisiti del database:

  • Le transazioni richiedono dati precisi e coerenti.
  • Per utilizzare in modo efficiente le risorse, 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 eseguite in un'operazione simultanea.

L'isolamento seriale definisce il livello di isolamento più elevato. L'isolamento seriale significa che:

  • Puoi presumere che il database esegua le transazioni in serie.
  • Le transazioni non sono interessate dai cambiamenti non applicati nelle operazioni simultanee.

Questa garanzia deve essere valida anche quando il database esegue più transazioni in parallelo. Il database deve implementare controlli di contemporaneità per risolvere i conflitti che potrebbero compromettere la garanzia.

Firestore garantisce l'isolamento seriale delle transazioni. Le transazioni in Firestore sono serializzate e isolate dai tempi di commit.

Isolamento serializzabile per tempo di commit

Firestore assegna a ogni transazione un tempo di commit che rappresenta un singolo momento. Quando Firestore esegue il commit delle modifiche di una transazione nel database, puoi presumere che tutte le operazioni di lettura e scrittura all'interno della transazione abbiano luogo esattamente al momento del commit.

L'esecuzione effettiva di una transazione richiede un determinato periodo di tempo. L'esecuzione di una transazione inizia prima della scadenza del commit e l'esecuzione di più operazioni può sovrapporsi. Firestore garantisce l'isolamento serializzabile e garantisce che:

  • Firestore esegue il commit delle transazioni in base all'ora di commit.
  • Firestore isola le transazioni dalle operazioni simultanee con un tempo di commit successivo.

Nel caso di contese di dati tra operazioni simultanee, Firestore utilizza controlli di contemporaneità ottimistici e pessimistici per risolvere la controversia.

Isolamento in 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 visualizzano i risultati delle scritture precedenti all'interno della transazione. Anche se modifichi o elimini un documento all'interno di una transazione, tutti i documenti letti in tale transazione restituiscono la versione del documento in fase di commit, prima delle operazioni di scrittura della transazione. Le operazioni di lettura non restituiscono nulla se il documento non esisteva.