Contesa dei dati nelle transazioni

Questa pagina descrive la contesa dei dati transazionali, la serializzabilità e l'isolamento. Per esempi di codice delle transazioni, consulta transazioni e scritture batch.

Transazioni e controversie relative ai dati

Affinché una transazione abbia esito positivo, i documenti recuperati dalle operazioni di lettura devono non essere modificati dalle operazioni esterne alla transazione. Se un'altra operazione tenta di modificare uno di questi documenti, l'operazione entra in uno stato di contesa dei dati con la transazione.

Conflitto 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 contesa dei dati ritardando o non superando una delle operazioni. Le librerie client di Firestore ritentano automaticamente le transazioni non riuscite a causa di una contesa dei dati. Dopo un numero infinito 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 decidi quale operazione non riuscire o ritardare, il comportamento dipende dal tipo di libreria client.

  • Gli SDK mobile/web utilizzano controlli di contemporaneità ottimistici.

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

Contesa dei dati negli SDK per dispositivi mobili/web

Gli SDK per dispositivi mobili/web (piattaforme Apple, Android, Web, C++) utilizzano controlli di contemporaneità ottimistica per risolvere i conflitti di dati.

Controlli di contemporaneità ottimistica
Supponendo che la contesa dei dati non sia probabile o che non sia efficiente mantenere i blocchi dei database. Le transazioni ottimistiche non utilizzano i blocchi del database per impedire ad altre operazioni di modificare i dati.

Gli SDK mobile/web utilizzano controlli ottimistici di contemporaneità, perché possono operare in ambienti con elevata latenza e una connessione di rete inaffidabile. Il blocco dei documenti in un ambiente ad alta latenza causerebbe troppi errori di conflitti dei dati.

Negli SDK per dispositivi mobili/web, una transazione tiene traccia di tutti i documenti letti all'interno della transazione. 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 prova nuovamente a eseguire la transazione. Se la transazione non riesce a ottenere un risultato chiaro dopo alcuni nuovi tentativi, non va a buon fine a causa di un conflitto di dati.

Conflitto dei dati nelle librerie client del server

Le librerie client del server (C#, Go, Java, Node.js, PHP, Python, Ruby) utilizzano controlli di contemporaneità pessimistici per risolvere i conflitti tra i dati.

Controlli di contemporaneità pessimistici
In base al presupposto che è probabile una contesa tra i dati. Le transazioni pessimistiche utilizzano i blocchi del database per impedire ad altre operazioni di modificare i dati.

Le librerie client server utilizzano controlli pessimistici di contemporaneità, in quanto presuppongono una bassa latenza e una connessione affidabile al database.

Nelle librerie client del server, le transazioni applicano blocchi ai documenti letti. Il blocco di una transazione su un documento 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, sblocca 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.

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 proviene dai seguenti requisiti di 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 provenienti da modifiche di cui non è stato eseguito il commit in un'operazione contemporanea.

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 da modifiche non impegnate in operazioni simultanee.

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

Firestore garantisce l'isolamento serializzabile delle transazioni. Le transazioni in Firestore sono serializzate e isolate in base al tempo 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 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 della data di commit e l'esecuzione di più operazioni potrebbe sovrapporsi. Firestore supporta l'isolamento serializzabile e garantisce che:

  • Firestore esegue il commit delle transazioni in ordine in base all'ora di commit.
  • Firestore isola le transazioni dalle operazioni concomitanti con un'ora di commit successiva.

In caso di contesa di dati tra operazioni simultanee, Firestore utilizza controlli di contemporaneità ottimistici e pessimistici per risolvere i conflitti.

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 di quella transazione. Anche se modifichi o elimini un documento all'interno di una transazione, tutte le letture dei documenti nella 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 con la contesa dei dati

Per ulteriori informazioni sui conflitti di dati e su come risolverli, consulta la pagina per la risoluzione dei problemi.