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 le letture e le scritture simultanee, influenzando le prestazioni, la latenza e le percentuali 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.
- L'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. Puoi anche utilizzare la concorrenza pessimistica con l'isolamento di lettura ripetibile.
Concorrenza pessimistica nell'isolamento serializzabile
Questa modalità presuppone che le transazioni simultanee possano competere per gli stessi dati. Acquisisce i 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.
Nella concorrenza pessimistica, 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 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 entrambe 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.
Concorrenza pessimistica nell'isolamento di lettura ripetibile
Utilizza la concorrenza pessimistica nell'isolamento di lettura ripetibile per serializzare le scritture. In questa modalità, le operazioni di lettura utilizzano gli snapshot, ma
i blocchi esclusivi
si applicano ai dati letti dalle FOR UPDATE query o dai
lock_scanned_ranges=exclusive suggerimenti e ai dati scritti con le query DML.
Vantaggi della concorrenza pessimistica con l'isolamento serializzabile
Il vantaggio principale dell'utilizzo della concorrenza pessimistica con l'isolamento serializzabile è che, nei carichi di lavoro altamente contenziosi, aiuta le transazioni a progredire. Spanner assegna la priorità alle transazioni precedenti rispetto a quelle più recenti durante i conflitti, assicurandosi che le transazioni vengano completate e riducendo al contempo il numero di transazioni interrotte ripetutamente.
Vantaggi della concorrenza pessimistica con l'isolamento di lettura ripetibile
Con l'isolamento di lettura ripetibile, le transazioni che acquisiscono blocchi potrebbero comunque essere interrotte al momento del commit se i dati letti come parte di una query con FOR UPDATE o come parte di una query DML sono stati modificati da una transazione simultanea prima del commit della transazione. Tuttavia, dopo l'acquisizione dei blocchi, impedisce ulteriori aggiornamenti simultanei fino al commit della transazione, serializzando le scritture.
Rischi della concorrenza pessimistica
La concorrenza pessimistica con l'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 il mantenimento dei blocchi per un lungo periodo di tempo, bloccando potenzialmente altre operazioni.
Casi d'uso della concorrenza pessimistica con l'isolamento serializzabile
La concorrenza pessimistica è adatta ai carichi di lavoro con elevata contesa di lettura-scrittura e scrittura-scrittura. È appropriata anche quando le interruzioni e i nuovi tentativi delle transazioni sono costosi. Utilizza questa modalità predefinita a meno che il tuo carico di lavoro non presenti ritardi eccessivi nei blocchi a lunga esecuzione o non sia influenzato in modo significativo dai conflitti di blocco.
Casi d'uso della concorrenza pessimistica con l'isolamento di lettura ripetibile
Utilizza la concorrenza pessimistica con la lettura ripetibile per i carichi di lavoro che richiedono una clausola FOR UPDATE o query DML per acquisire i blocchi. Questo approccio è particolarmente utile per i carichi di lavoro di cui è stata eseguita la migrazione a Spanner da altri database che acquisiscono blocchi per queste istruzioni.
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 in modo che utilizzi controllo della contemporaneità ottimistico.
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. In questo modo, nessuna altra transazione di cui è stato eseguito il commit simultaneamente ha 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 momento del commit.
Per letture e query
Le letture e le query non sono bloccate. Tutte le letture e le query all'interno di una transazione ottimistica vengono eseguite in un singolo timestamp di 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 di cui è stato eseguito il commit prima della prima lettura o query.
Per letture e scritture
Per una transazione ottimistica con letture e scritture, Spanner esegue un passaggio di convalida al momento del commit. Il commit della transazione viene eseguito correttamente solo se non vengono rilevati conflitti e se vengono soddisfatte le seguenti condizioni:
- Nessuna scrittura di cui è stato eseguito il commit simultaneamente è in conflitto con i dati letti da questa transazione, ovvero non sono stati eseguiti commit di scritture dopo il timestamp di lettura, ma prima del commit delle scritture di questa transazione.
- Lo schema non è stato modificato dal 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 elevata contesa, le transazioni ottimistiche potrebbero essere interrotte ripetutamente. Al contrario, le transazioni pessimistiche risolvono i conflitti di lettura-scrittura consentendo il 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 di 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 elevata contesa di lettura-scrittura quando viene utilizzata con l'isolamento serializzabile. Comprendi questi rischi prima di utilizzare controllo della contemporaneità ottimistico con l'isolamento serializzabile per il tuo carico di lavoro.
- In caso di elevata contesa di lettura-scrittura, le transazioni ottimistiche potrebbero riscontrare un'elevata percentuale di interruzioni, 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 della mancanza di transazioni.
Casi d'uso della concorrenza ottimistica
La concorrenza ottimistica è adatta ai carichi di lavoro transazionali con bassa contesa di lettura-scrittura. Per le transazioni serializzabili, è utile anche per i carichi di lavoro che possono tollerare le interruzioni delle transazioni.
Valuta la concorrenza ottimistica per i seguenti carichi di lavoro:
- 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 i ritardi causati dai blocchi di lettura. Ad esempio, le transazioni nei client mobile con connessioni lente o le transazioni con SLA basso che mantengono i 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 pubblicare le letture a livello regionale, ridurre le latenze di lettura ed evitare problemi di produzione dovuti al traffico di lettura con picchi in una suddivisione attiva. Migliora anche la disponibilità di lettura durante il sovraccarico o l'indisponibilità 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 percentuali di interruzione elevate 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.
Configurare 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#
C++
REST
L'API REST TransactionOptions
di Spanner fornisce un'enumerazione ReadLockMode all'interno del messaggio ReadWrite che
ti 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 ti 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 ogni 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.