Serializzabilità e isolamento delle transazioni

Questa pagina descrive il conflitto, la serializzabilità e l'isolamento dei dati transazionali. Per esempi di codici di transazione, vedere invece transazioni e scritture in batch .

Transazioni e conflitto di dati

Affinché una transazione abbia successo, i documenti recuperati dalle sue operazioni di lettura devono rimanere non modificati da operazioni esterne alla transazione. Se un'altra operazione tenta di modificare uno di questi documenti, tale operazione entra in uno stato di conflitto di dati con la transazione.

Contesa sui 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 del campo di quel documento.

Cloud Firestore risolve il conflitto sui dati ritardando o fallendo una delle operazioni. Le librerie client Cloud Firestore ritentano automaticamente le transazioni che non riescono a causa di un conflitto di dati. Dopo un numero finito di tentativi, l'operazione di transazione fallisce e restituisce un messaggio di errore:

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

Quando si decide quale operazione fallire o ritardare, il comportamento dipende dal tipo di libreria client.

  • Gli SDK per dispositivi mobili/Web utilizzano controlli di concorrenza ottimistici.

  • Le librerie client del server utilizzano controlli di concorrenza pessimistici.

Contesa di dati negli SDK per dispositivi mobili/Web

Gli SDK per dispositivi mobili/Web (piattaforme Apple, Android, Web, C++) usano controlli di concorrenza ottimistici per risolvere i conflitti di dati.

Controlli ottimistici della concorrenza
Basato sul presupposto che il conflitto dei dati non è probabile o che non è efficiente mantenere i blocchi del database. Le transazioni ottimistiche non utilizzano i blocchi del database per impedire ad altre operazioni di modificare i dati.

Gli SDK per dispositivi mobili/Web utilizzano controlli di concorrenza ottimistici, perché possono funzionare in ambienti con latenza elevata e una connessione di rete inaffidabile. Bloccare i documenti in un ambiente a latenza elevata causerebbe troppi errori di conflitto dei dati.

Negli SDK Mobile/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 qualche documento è cambiato, il gestore della transazione ritenta la transazione. Se la transazione non riesce a ottenere un risultato pulito dopo alcuni tentativi, la transazione fallisce a causa di un conflitto di dati.

Conflitto di dati nelle librerie client del server

Le librerie client del server (C#, Go, Java, Node.js, PHP, Python, Ruby) utilizzano controlli di concorrenza pessimistici per risolvere il conflitto dei dati.

Controlli di concorrenza pessimistici
Basato sul presupposto che sia probabile un conflitto di dati. Le transazioni pessimistiche utilizzano i blocchi del database per impedire ad altre operazioni di modificare i dati.

Le librerie client del server utilizzano controlli di concorrenza pessimistici perché presuppongono una bassa latenza e una connessione affidabile al database.

Nelle librerie client del server, le transazioni bloccano i documenti che leggono. Il blocco di una transazione su un documento impedisce ad altre transazioni, scritture batch e scritture non transazionali di modificare quel documento. Una transazione rilascia i blocchi del documento al momento del commit. Inoltre rilascia i suoi blocchi se scade o fallisce 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 loro blocchi in ordine cronologico.

Isolamento serializzabile

Il conflitto dei dati tra le transazioni è strettamente correlato ai livelli di isolamento del database. Il livello di isolamento di un database descrive il modo in 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 in modo efficiente le risorse, i database eseguono 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 non confermate in un'operazione simultanea.

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

  • Si può supporre che il database esegua transazioni in serie.
  • Le transazioni non sono influenzate dalle modifiche non confermate nelle operazioni simultanee.

Questa garanzia deve valere anche mentre il database esegue più transazioni in parallelo. Il database deve implementare controlli di concorrenza per risolvere i conflitti che potrebbero violare questa garanzia.

Cloud Firestore garantisce l'isolamento serializzabile delle transazioni. Le transazioni in Cloud Firestore vengono serializzate e isolate in base al tempo di commit.

Isolamento serializzabile in base al tempo di commit

Cloud Firestore assegna a ciascuna transazione un tempo di commit che rappresenta un singolo momento. Quando Cloud Firestore esegue il commit delle modifiche di una transazione nel database, puoi presupporre che tutte le letture e le scritture all'interno della transazione avvengano esattamente al momento del commit.

L'effettiva esecuzione di una transazione richiede un certo lasso di tempo. L'esecuzione di una transazione inizia prima del tempo di commit e l'esecuzione di più operazioni potrebbe sovrapporsi. Cloud Firestore mantiene l'isolamento serializzabile e garantisce che:

  • Cloud Firestore esegue il commit delle transazioni in base al 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 di concorrenza ottimistici e pessimistici per risolvere il conflitto.

Isolamento all'interno di una transazione

L'isolamento della transazione 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 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 con il conflitto dei dati

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