La concorrenza ottimistica per oggetto implica la serializzazione se una transazione non si estenderà mai su più oggetti?


13

Dato un sistema che fornisce:

  • Controllo della concorrenza / versioning ottimistico per oggetto (utilizzando CAS - Check-and-Set)
  • Transazioni che non devono mai estendersi oltre un singolo oggetto.
  • Isolamento di istantanee

Questo sistema è considerato serializzabile ?

Dall'isolamento dell'istantanea

In un'anomalia dell'inclinazione in scrittura, due transazioni (T1 e T2) leggono contemporaneamente un set di dati sovrapposti (ad es. Valori V1 e V2), eseguono contemporaneamente aggiornamenti disgiunti (ad es. Aggiornamenti T1 V1, aggiornamenti T2 V2) e infine eseguono il commit simultaneo, senza aver mai visto l'aggiornamento eseguito dall'altro. Se il sistema fosse serializzabile, tale anomalia sarebbe impossibile, in quanto T1 o T2 dovrebbero verificarsi "prima" ed essere visibili all'altro. Al contrario, l'isolamento dell'istantanea consente di scrivere anomalie di inclinazione.

Come esempio concreto, immagina che V1 e V2 siano due equilibri detenuti da una sola persona, Phil. La banca consentirà a V1 o V2 ​​di presentare un deficit, a condizione che il totale detenuto in entrambi non sia mai negativo (cioè V1 + V2 ≥ 0). Entrambi i saldi sono attualmente $ 100. Phil avvia due transazioni contemporaneamente, T1 preleva $ 200 da V1 e T2 preleva $ 200 da V2.

Sulla base di ciò sembra che avere il potenziale di inclinazione in scrittura sia l'unica ragione per un sistema che garantisce che l'isolamento di istantanee non sia serializzabile.

Tuttavia, in un sistema che non consente a una transazione di estendersi su più oggetti (nell'esempio precedente V1 e V2) sembra impossibile che si verifichino errori di scrittura .

Pertanto, il sistema sopra descritto è serializzabile. È corretto?


1
Penso che la risposta sia sì, a condizione che al database sia consentito interrompere le transazioni che altrimenti introdurrebbero incoerenza in scrittura - se le transazioni sono limitate a leggere / scrivere un singolo oggetto, allora sono disgiunte o in collisione.
pjc50,

2
Penso che avresti anche bisogno di un modo per evitare record duplicati per un commit iniziale. In questo caso, due scrittori ottimisti potevano vedere ciascuno un'istantanea vuota e che il record era nuovo e quindi si potevano avere due oggetti, ciascuno alla versione 0.
Matthew Mark Miller,

Risposte:


1

No, non credo che le tue disposizioni risultino in un sistema che dovremmo considerare serializzabile.

L'isolamento dello snapshot è una tecnica che garantisce che una transazione veda lo stesso set di dati nell'intera transazione. L'isolamento dello snapshot fornisce alcune garanzie, ma non definisce tutte le caratteristiche necessarie per capire come funzionano veramente le transazioni (a meno che non scegliamo di confondere l'isolamento dello snapshot e MVCC).

L'isolamento dello snapshot è più comunemente implementato usando MVCC, Multi Version Coistency Control. MVCC definisce più dettagli delle transazioni nel contesto delle loro istantanee: si dice che richiedono l'isolamento solo quando si scrive un conflitto (solo posizioni, o posizioni + valori, a seconda dell'implementazione). MVCC fornisce un modello di coerenza rilassato e soffre di inclinazione di scrittura.

I modelli di coerenza rilassata sono difficili da capire perché sono come un ibrido tra nessun isolamento e completo isolamento.

Quindi, iniziamo con un rigoroso modello di concorrenza prima. Due transazioni devono essere isolate l'una dall'altra se una scrive su dati che l'altra legge o scrive (e viceversa ...).

Quando non sappiamo perché una transazione legge i dati, dobbiamo presumere che un valore diverso possa alterare il comportamento del cliente coinvolto, motivo per cui la condizione di transazioni sovrapposte indica l'isolamento. Senza isolamento, una lettura di dati non aggiornati in un'istantanea può facilmente mostrare una coerenza rilassata, un altro termine per il quale è incoerenza, vale a dire errore.

Dobbiamo solo considerare i dati esatti letti o scritti dalle transazioni, non è necessario prendere in considerazione tutti i dati al di fuori di quel set. Tuttavia, è fondamentale rendersi conto che quando stiamo parlando di dati letti da una transazione, dobbiamo necessariamente includere tutti i dati "meta" (e dati e metadati letti da meta operazioni come il controllo dei vincoli). Esempi di metadati sono / meta operazioni sono: identificazione di una nuova chiave primaria unica; un altro è la somma di un'intera colonna; un altro è cercare qualcosa e non trovarlo; intervallo di ricerche o somme. Questo va al commento di @ Matthew sulla prevenzione dei duplicati, così come la risposta di @Tersosauros, in cui considera lo stato.

Ad esempio, ciò significa che due transazioni si sovrappongono (richiedono l'isolamento) quando entrambe inseriscono una riga (presupponendo un vincolo di chiave primaria univoco) poiché il controllo del vincolo di chiave è sinonimo di lettura dell'intera colonna di chiave primaria. Come altro esempio, cercare qualcosa e trovarlo è come leggere quel valore, tuttavia, non trovarlo è come guardare ogni valore nella colonna.

MVCC protegge solo da scritture sovrapposte o in conflitto, ma non protegge dalle letture (a meno che non siano scritte anche da quella transazione). Pertanto, per ottenere un errore di coerenza in MVCC, tutto ciò che dobbiamo fare è leggere qualcosa che viene modificato da un'altra transazione (in cui l'altra transazione avviene dopo l'istantanea del primo, ma si impegna per prima), mentre l'altra transazione continua a utilizzare dati non aggiornati e prende qualsiasi decisione in modo diverso sulla base di quei dati obsoleti rispetto a ciò che avrebbe fatto dati aggiornati. È più facile da causare di quanto si pensi.

La coerenza rilassata è un altro modo di dire potenzialmente incoerente o soggetto a errori. (La coerenza rilassata non deve essere confusa con l'eventuale coerenza, che è un'altra forma popolare diversa di errore soggetta a "NoSQL".)

Alla tua domanda, quando dici che le transazioni non devono mai estendersi a più di un oggetto, questo deve valere sia per le letture e le scritture, sia per i metadati (e le meta-operazioni), inclusi controllo di coerenza, aggregati di colonne intere, controlli di assenza, ricerche di intervallo, ecc. .: se è così, allora finora tutto bene.

Tuttavia...

Prendo dalla tua domanda che stai usando l'isolamento di istantanee (MVCC) su singoli oggetti (diciamo piuttosto che il blocco degli oggetti). (Parli anche di CAS; ho sentito parlare di confronta-e-scambia e, test-and-set, ma non check-and-set, anche se presumo che sia simile).

La tua domanda scritta mi suggerisce che gli "oggetti" hanno più di un campo, altrimenti le clausole della domanda non sarebbero necessarie.

Pertanto, poiché gli oggetti gestiti dallo snapshot / gestiti da MVCC hanno più di un campo, si è inclini a scrivere inclinazioni all'interno di singoli oggetti. Se due transazioni aggiornano lo stesso oggetto contemporaneamente, è possibile leggere un campo del valore dell'oggetto reso obsoleto da un'altra transazione simultanea sullo stesso oggetto e continuare senza conoscere, quindi, potenziali incoerenze (ovvero errori).

È possibile utilizzare invece il blocco degli oggetti, che impedirebbe a due transazioni (per l'aggiornamento) di guardare lo stesso oggetto anche se un'altra transazione fosse già in procinto di farlo.

Credo che una forma alternativa di isolamento dello snapshot possa essere eseguita senza utilizzare il modello di confronto del solo set di scrittura rotto di MVCC. Quindi, puoi (algoritmicamente) promuovere il set di confronto da sola scrittura per includere anche il set di lettura. Quindi due transazioni che aggiornano lo stesso oggetto non sarebbero in grado di causare l'inclinazione della scrittura (perché quella che tenta di eseguire il commit in seguito verrebbe interrotta). Penso che questa potrebbe essere la soluzione appropriata al problema che stai descrivendo, perché stai già ottenendo la maggior parte del vantaggio che MVCC ci acquisterebbe, precludendo le transazioni multi-oggetto.

(Dobbiamo solo considerare gli articoli / campi esatti e specifici letti o scritti, ma dobbiamo includere quelli letti come metadati, potenzialmente durante le meta-operazioni per prevenire l'inclinazione della scrittura (es. Errore). Se rimuoviamo il set letto dal set di confronto o non consideriamo i metadati (potenzialmente utilizzati dalle meta operazioni), quindi abbiamo un modello che consentirà l'errore.)


0

Penso, come affermato da @ pjc50 , (enfasi aggiunta :) " se le transazioni sono limitate a leggere / scrivere un singolo oggetto", allora "la risposta è sì". Tuttavia, penso che la caduta di questo sia nell'idea di un singolo oggetto.

Nell'esempio preso dall'isolamento dell'istantanea , T1 e T2 non condividono alcun valore. Tuttavia, sono ancora potenziali per un'inclinazione di scrittura perché " nessuno dei due [ha] visto l'aggiornamento eseguito dall'altra " sorgente . Pertanto, è la capacità di una transazione di vedere tutti gli altri aggiornamenti prima del commit che rende una transazione veramente serializzabile.

Dalla serializzabilità :

Serializzabilità di un programma significa equivalenza (nel risultato, lo stato del database, i valori dei dati) a un programma seriale (cioè sequenziale senza sovrapposizione di transazioni nel tempo) con le stesse transazioni.

Sfortunatamente, a causa di ciò (e come sottolinea @Matthew Mark Miller ), dobbiamo considerare anche lo stato e i valori. Con questa considerazione, due transazioni che utilizzano OCC avrebbero il potenziale di scrivere in disordine ogni volta che viene scritto uno stato del database .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.