Le transazioni Spanner offrono due modalità di controllo della contemporaneità: pessimistica e ottimistica. La scelta della modalità di controllo della contemporaneità influisce sul modo in cui le transazioni gestiscono letture e scritture simultanee, influenzando prestazioni, latenza e tassi di interruzione delle transazioni. Scegli la modalità più adatta ai requisiti di prestazioni e coerenza della tua applicazione.
Il comportamento predefinito dipende dal livello di isolamento utilizzato dalla transazione:
- L'isolamento serializzabile utilizza controllo della contemporaneità pessimistico per impostazione predefinita.
- Isolamento di lettura ripetibile, utilizza controllo della contemporaneità ottimistico per impostazione predefinita.
Controllo della contemporaneità pessimistico
Per impostazione predefinita, Spanner utilizza la concorrenza pessimistica con l'isolamento serializzabile. Questa modalità presuppone che le transazioni simultanee possano competere per gli stessi dati. Acquisisce blocchi in modo proattivo sui dati durante la lettura o la scrittura all'interno di una transazione. Verifica inoltre che i blocchi acquisiti in precedenza nella transazione rimangano attivi nelle istruzioni successive. Quando Spanner rileva un conflitto di blocco, utilizza l'algoritmo wound-wait per risolverlo.
Nel controllo della concorrenza pessimistico, le transazioni acquisiscono blocchi sui dati durante le fasi di esecuzione e commit della transazione.
- Per le letture:quando una transazione legge i dati, acquisisce un
blocco di lettura condiviso (
ReaderShared) durante la fase di esecuzione. Questi blocchi vengono mantenuti fino al commit della transazione. - Per DML e scritture:
- Durante l'esecuzione, per i dati modificati da DML o dalle scritture, la transazione potrebbe acquisire blocchi di lettura sull'esistenza delle righe.
- Al momento del commit, la transazione tenta di acquisire blocchi di scrittura o esclusivi per i dati scritti. I blocchi di scrittura bloccano le letture simultanee, ma potrebbero non bloccare le scritture simultanee, soprattutto quando entrambi utilizzano blocchi di scrittura. Ciò significa che più transazioni possono procedere al commit e i conflitti di scrittura-scrittura vengono risolti al momento del commit utilizzando l'algoritmo wound-wait. Tutti i blocchi vengono mantenuti fino al commit della transazione.
Vantaggi della concorrenza pessimistica con isolamento serializzabile
Il vantaggio principale dell'utilizzo della concorrenza pessimistica con l'isolamento serializzabile è che, nei carichi di lavoro altamente controversi, aiuta le transazioni a progredire. Spanner dà la priorità alle transazioni meno recenti rispetto a quelle più recenti durante i conflitti, garantendo che le transazioni vengano completate alla fine riducendo la quantità di transazioni interrotte ripetutamente.
Rischi della concorrenza pessimistica
La concorrenza pessimistica con isolamento serializzabile presenta i seguenti rischi:
- Le letture a lunga esecuzione potrebbero bloccare le scritture sensibili alla latenza.
- Le transazioni che prevedono l'interazione dell'utente prima del completamento potrebbero causare blocchi per un lungo periodo di tempo, bloccando potenzialmente altre operazioni.
Casi d'uso per la concorrenza pessimistica
La concorrenza pessimistica è adatta per i workload con elevata contesa di lettura/scrittura e scrittura/scrittura. È appropriato anche quando gli annullamenti e i nuovi tentativi di transazione sono costosi. Utilizza questa modalità predefinita, a meno che il tuo workload non presenti ritardi eccessivi di blocco prolungato o non sia interessato in modo significativo da conflitti di blocco.
Controllo della contemporaneità ottimistico
Spanner fornisce anche controllo della contemporaneità ottimistico. Quando utilizzi l'isolamento di lettura ripetibile, la modalità predefinita è il controllo della concorrenza ottimistico. Puoi anche configurare l'isolamento serializzabile per utilizzare controllo della contemporaneità ottimistico.
Il controllo della contemporaneità ottimistico presuppone che i conflitti siano rari. Le letture e le query anche all'interno di una transazione di lettura/scrittura procedono senza acquisire blocchi.
Con l'isolamento serializzabile predefinito di Spanner, le letture vengono
convalidate al momento del commit. Ciò garantisce che nessun'altra transazione di cui è stato eseguito il commit contemporaneamente abbia modificato i dati letti in precedenza dalla transazione. Se utilizzi
l'isolamento di lettura ripetibile,
le letture con un suggerimento FOR UPDATE o lock_scanned_ranges=exclusive
vengono convalidate al momento del commit. Se Spanner rileva un conflitto, interrompe la transazione.
Come funziona la concorrenza ottimistica
La concorrenza ottimistica modifica il modo in cui Spanner esegue le letture, le query e i commit delle transazioni. Esegue l'esecuzione senza blocchi durante la fase di lettura e convalida la coerenza al commit.
Per letture e query
Le letture e le query sono senza blocchi. Tutte le letture e le query all'interno di una transazione ottimistica vengono eseguite in un unico timestamp dello snapshot. Spanner sceglie questo timestamp quando viene eseguita la prima lettura o query. In questo modo, tutte le letture e le query successive all'interno della transazione vedono le scritture eseguite prima della prima lettura o query.
Per letture e scritture
Per una transazione ottimistica con operazioni di lettura e scrittura, Spanner esegue un passaggio di convalida al momento del commit. Il commit della transazione va a buon fine solo se non vengono rilevati conflitti e sono soddisfatte le seguenti condizioni:
- Nessuna scrittura di cui è stato eseguito il commit contemporaneamente è in conflitto con i dati letti da questa transazione, ovvero non sono state eseguite scritture dopo il timestamp di lettura ma prima che questa transazione esegua il commit delle proprie scritture.
- Lo schema non è stato modificato dall'ultimo timestamp di lettura.
Il livello di isolamento determina l'insieme di letture convalidate. Con l'isolamento serializzabile, tutte le letture vengono convalidate. Con l'isolamento di lettura ripetibile,
le letture con un suggerimento FOR UPDATE o lock_scanned_ranges=exclusive vengono
convalidate al momento del commit.
In caso di contesa elevata, le transazioni ottimistiche potrebbero essere interrotte ripetutamente. Al contrario, le transazioni pessimistiche risolvono i conflitti di lettura/scrittura consentendo l'esecuzione del commit della transazione precedente e riprovando la transazione più recente.
Vantaggi della concorrenza ottimistica
La concorrenza ottimistica offre i seguenti vantaggi:
- Le letture non acquisiscono blocchi: le transazioni ottimistiche non acquisiscono blocchi per le letture, quindi le letture a lunga esecuzione non bloccano le scritture sensibili alla latenza.
- Latenza di commit ridotta per le transazioni di sola lettura: poiché tutte le letture all'interno di una transazione ottimistica si basano sullo stesso timestamp dello snapshot, non è necessario verificare la coerenza durante l'esecuzione o il commit per queste letture, il che riduce significativamente la latenza.
Rischi della concorrenza ottimistica
La concorrenza ottimistica introduce rischi, in particolare in caso di contesa di lettura/scrittura elevata se utilizzata con l'isolamento serializzabile. Comprendi questi rischi prima di utilizzare controllo della contemporaneità ottimistico con l'isolamento serializzabile per il tuo workload.
- In caso di contesa di lettura/scrittura elevata, le transazioni ottimistiche potrebbero subire un tasso di interruzioni elevato, perché le scritture simultanee potrebbero invalidare le letture di una transazione ottimistica.
- In caso di contesa elevata persistente, una transazione potrebbe essere interrotta ripetutamente e non essere mai eseguita a causa di starvation della transazione.
Casi d'uso per la concorrenza ottimistica
La concorrenza ottimistica è adatta per i workload transazionali con bassa contesa di lettura/scrittura. Per le transazioni serializzabili, avvantaggia anche i carichi di lavoro che possono tollerare gli annullamenti delle transazioni.
Prendi in considerazione la concorrenza ottimistica per i seguenti workload:
- Carichi di lavoro a bassa priorità e tolleranti alla latenza con transazioni a lunga esecuzione:utilizza la concorrenza ottimistica se le letture o le query a lunga esecuzione potrebbero ritardare le scritture sensibili alla latenza. In questo modo si evitano ritardi causati dai blocchi di lettura. Ad esempio, transazioni in client mobile con connessioni lente o transazioni con SLA basso che mantengono blocchi di lettura per molte righe o intervalli di grandi dimensioni.
- Carichi di lavoro transazionali sensibili alla latenza di lettura con bassa contesa di lettura/scrittura: In una configurazione multiregionale, utilizza la concorrenza ottimistica per gestire le letture a livello regionale, ridurre le latenze di lettura ed evitare problemi di produzione dovuti a picchi di traffico di lettura in una suddivisione calda. Migliora inoltre la disponibilità di lettura durante il sovraccarico o la mancata disponibilità del leader.
- Carichi di lavoro transazionali in cui la maggior parte delle transazioni è di sola lettura: il passaggio alla concorrenza ottimistica riduce la latenza di commit per le transazioni di sola lettura comuni in questi carichi di lavoro. Assicurati che la contesa di lettura/scrittura sia bassa per evitare tassi di interruzione elevati per le transazioni di lettura/scrittura.
Evita di utilizzare la concorrenza ottimistica per i carichi di lavoro transazionali sensibili alla latenza in cui i conflitti di lettura/scrittura sono frequenti.
Configura controllo della contemporaneità
Puoi utilizzare le librerie client, l'API REST e l'API RPC di Spanner per specificare la modalità di concorrenza per le transazioni di lettura/scrittura.
Librerie client
Java
Go
Node.js
Python
C#
REST
L'API REST TransactionOptions di Spanner
fornisce un'enumerazione ReadLockMode all'interno del messaggio ReadWrite che
consente di selezionare la modalità di blocco PESSIMISTIC o OPTIMISTIC.
RPC
L'API RPC Transactionoptions di Spanner
fornisce un'enumerazione ReadLockMode all'interno del messaggio ReadWrite che
consente di selezionare la modalità di blocco PESSIMISTIC o OPTIMISTIC.
Driver
Puoi utilizzare i driver di Spanner per impostare read_lock_mode come
parametro di connessione a livello di connessione o come opzione dell'istruzione SET
a livello di transazione. Per saperne di più su ciascun driver, consulta la
panoramica dei driver.
Passaggi successivi
- Scopri di più sui livelli di isolamento di Spanner.
- Scopri come utilizzare l'isolamento di lettura ripetibile.