La mutua esclusione regola l'accesso concorrente ad una risorsa. Quando un processo ha bisogno di accedere piu' risorse in modo esclusivo, nascono problemi dovuti ad una possibile inconsistenza e/o possibile perdita di dati.
Esempio 1: Race condition

Esempio 2: Perdita di dati a causa di crash
Il C/C A contiene 50MIl primo problema nasce da una non corretta serializzazione delle operazione di accesso sui 2 C/C da parte dei 2 processi.
Il C/C B contiene 19M
Esecuzione:
Leggo dal C/C A
Sottraggo 1M
Scrivo sul C/C A (49M)
Leggo dal C/C B
Sommo 1M sul C/C B
<------------Crash
Scrivo C/C B (11M)Risultato: il C/C A contiene 49M, il C/C B contiene 10M
Esempio 3: Possibili serializzazioni di esecuzioni concorrenti
Crediti inizialiRequisiti richiesta ad un sistema di controllo
C/C A credito di 20M
C/C B credito di 10M
C/C C credito di 5MProcesso T1
begin
1 read credito A
2 read credito B
3 write credito A-10M su C/C a
4 write credito B+10M su C/C B
end
Processo T2
begin
1 read credito B
2 read credito C
3 write credito B-5M su C/C B
4 write credito C+5M su C/C C
endRisultato corretto: C/C A = 10M, C/C B = 15M, C/C C = 10M
Esempio di sequenza corretta:
T1.1, T2.1, T2.2, T2.3, T1.2, T1.3, T1.4, T2.4Esempio di sequnza non corretta:
T1.1, T2.1, T2.2, T1.2, T2.3, T1.3, T1.4, T2.4
Stable Storage (Indice)
Proprieta' (Indice)
2. Atomicita'
Le transazioni sono chiamate anche talvolta azioni atomiche.
L'azione atomica e' una astrazione che ha avuto diverse definizioni
diverse, ad esempio:
3. Permanenza
Dopo che una transazione ha effettuato un commit, i risultati devono
essere visibili e permanenti. In un nesting di transazioni ognuna e' committed
"relativamente al suo parent".
Implementazione
dell'atomicita'
in previsione di failure
(Indice)
Sono 2 i punti da considerare:
A. private work space
Ogni transazione ha il suo private workspace in cui ricopia tutti i
file e i dati che modifichera'. Lo stesso avviene per eventuali nested
transaction. E' un metodo molto costoso.
B.Utilizzo di shadow block dei file
Solo i blocchi di file modificati o aggiunti sono ricopiati. Nel private
workspace viene mantenuto solo l'indice (modificato) dei blocchi dei file.
Gli altri processi vedono quindi sempre i blocchi originali dei file, finche'
un processo non effettua il commit di una transazione. In questo caso l'indice
del private work space viene ricopiato in modo atomico su quello originale.
Questo sistema deve essere accoppiato con un sistema di lock o di controllo
ottimistico per escludere situazione di inconsistenza dovuto all'accesso
concorrente in scrittura da parte di piu' processi in diverse transazioni.
C. Utilizzo di writeahead log.
I blocchi del file vengono effettivamente scritti, ma e' mantenuta
una traccia delle modifiche sotto forma di coppia vecchio-valore / nuovo-valore.
Se la transazione effettua un commit, il log e' cancellato. Se abortisce,
le modifiche apportate sono recuperate (roll-back).
I file non sono le uniche risorse richiedibili in una transazione. >si possono anche richiedere dei servizi al sistema. In questo caso le risorse sono dei server. Se un servizio cambia stato in conseguenza della transazione, occorre fare una copia anche del server (ad es. in un servizio di file system distribuito, puo' rimanere l'impostazione della working directory). E' necessario allora fare una copia dello stato del server.
2. Two phase commit protocol
Se una transazione abortisce (volontariamente, o per failure di un
componente) bisogna riportare il sistema alla situazione precedente, con
un'operazione undo.
Occorre quindi memorizzare (su un file log) le operazioni che sono
state fatte e le risorse che sono state accedute (per farne poi il roll-back).
Le operazioni possibili sulla transazione sono:
DO esegue làazione e scrive il log
UNDO recupera (torna indietro) le operazioni scritte sul log
REDO riesegue le operazioni scritte sul log.
Il two phase commit protocol consente di effettuare il commitment finale se non si verifica un failure. In caso di failure invece e' possibile riparare il guasto (ad esempio rilanciare un processo che si e' interrotto, riconoscere la precedente esecuzione, riportare lo stato del sistema nella posizione corretta....)
Non fatto
Implementazione della serializzabilita' (Indice)
Abbiamo visto prima l'implementazione dell'atomicita' come possibilita'
di effettuare un UNDO della transazione, e come esecuzione del "tutto o
niente" dell'operazione finale di commit.
L'atomicita' deve pero' essere estesa a tutta la transazione, cioe'
non deve essere visibile dall'esterno nessun suo stato intermedio.
Inoltre bisogna coordinare l'accesso alle risorse in modo da evitare (o
rompere) il deadlock. Il meccanismo che consente il completamento dell'atomicita'
consente anche di ottenere uno schedule consistente, e si chiama
1. Locking
E' il sistema piu' semplice: ogni oggetto ha un solo lock, ottenibile
da una sola transazione alla volta. se una transazione cerca di fare un
lock su un oggetto gia' bloccato, puo' aspettare, abortire o interrompere
(e causarne il roll-back) l'altra transazione, per evitare di finire in
deadlock.
Una transazione e' ben formata se:
2PL: 2 Phase Lock

Transazione T1Le operazioni lock e unlock sono evidenziate nel programma, ma sono normalmente eseguite dal concurrency manager in risposta ad operazioni read/write.
begin
lock conto A
read credito A
lock conto B
read credito B
write credito A-10M su conto A
unlock conto A
write credito B+10M su conto B
unlock conto B
end
Nell'esempio fatto e' possibile un deadlock.
Si utilizzano in genere tecniche di deadlock detection, con interruzione
e recovery delle transazioni, associato con time-out.
I metodi di avoidance sono poco utili perche' non consentono la dinamicita',
soprattutto in ambiente distribuito.
Si puo' dimostrare che sae tutte le transazioni usano il 2PL, allora tutti gli schedule ottenibili sono serializzabili.
Ci possono essere ancora dei problemi di atomicita' in caso di failure (vedi dopo, effetto domino). In questo caso si puo' imporre che tutti i lock siano rilasciati solo dopo la fase di commit.
In ogni caso, se una risorsa fosse acquisita e poi rilasciata prima del commit, si violerebbe comunque il concetto di atomicita', rendendo visibile uno stato intermedio prima del commit finale.
Effetto domino
I protocolli Two Phase Lock prevedono che le risorse siano rilasciate dopo averle tutte acquisite, e non ne siano piu' prese altre. Normalmente il rilascio viene effettuato come atto di terminazione. In questo modo si preserva l'atomicita' dell'azione e si impedisce l'effetto domino.
L'atomicita' perche' la stessa variabile non puo' essere acquisita piu' di una volta, rendendo cosi' visibile una zsua situazione intermedia:

L'effetto domino si ha quando una transazione fallisce, effettua il roll-back e trascina eventualmente con se' altre transazioni a causa dle recovery che effettua sulle risorse (se il commitment fosse fatto dopo aver rilasciato gia' delle risorse).

Nel caso precedente, l'effetto domino non e' neacnche il caso peggiore. Infatti se T2 fosse gia' stata committed al momento del failure di T1, ci si troverebbe in una situazione d'errore.
2. Metodo ottimistico
In questo caso ogni transazione lavora su di una copia delle risorse (ad esempio utilizzando il metodo di shadow block). Al momento del commit si verifica se nel frattempo ci sono o ci sono state altre transazioni che hanno utilizzato le stesse risorse, in modo tale da rendere l'esecuzione corrente non consistente. In questo caso o si abortisce la transazione, o si causa l'abort di altre transazioni in corso. Per evitare starvation si utilizza il metodo del time stamp (identificatore unico, attribuito in modo da ottenere un ordinamento assoluto fra le transazioni) per selezionare la transazione che puo' sopravvivere.
Problema del deadlock (Indice)
Durante il lock delle risorse (nel caso di algoritmi di locking) e' ovviamente possibile il deadlock. In ambiente distribuito e soprattutto quando gli oggetti accessibili sono numerosi (tipo blocchi di file) e variano rapidamente con il tempo, abbiamo visto che i metodi di deadlock avoidance e prevention sono poco pratici. Il metodo di deadlock detection e recovery e' complicato dal fatto che occorre mantenere un allocation graph distribuito (problemi di sincronizzazione). Si utilizza in genere un metodo misto, di prevention-detection, basato sui time stamp.
Time Stamp
Un time stamp e' un numero unico assegnato ad una transazione (ad esempio
da un gestore centralizzato, oppure utilizzando un meccanismo distribuito
di clock logico) in modo monototono crescente.
Nell'esecuzione delle transazioni si da' la priorita' alle transazioni
che hanno il time stamp minore, in modo da garantire l'assenza di starvation.
Infatti, una volta assegnato un time stamp ad una transazione (che rimane
lo stesso anche se la transazione abortisce e poi ricomincia), solo un
numero finito di altre transazioni hanno la priorita' su di essa.
Si puo' utilizzare il time stamp nei sistema con lock per evitare il
deadlock, e nei sistemi ottimistici per effettuare il commit di una transazione
piuttosto che di un'altra.
Vediamo il primo casa.
In congiunzione con i lock
Ogni risorsa e' controllata da un gestore (processo) che si trova sullo
stesso host su cui e' collocata la risorsa. Un gestore riceve le richieste
da uno dei processi coinvolti in una transazioni, e memerizza lo stato
della risorsa.
Quando una risorsa e' gia' assegnata ad una transazione Tj (con time
stamp TSj) e il gestore riceve una richiesta da parte di un'altra transazione
Ti con time stamp TSi, puo' effettuare una delle seguenti azioni:
Ci sono diversi S.O. che mettono a disposizione primitive per la realizzazione di transazioni. Ad esempio:
Zeus, sistema distribuito sviluppato dall'Universita' del Minnesota e dalla Honeywell) per applicazioni object-oriented, basato sull'effettuazione di checkpoint degli oggetti (sono file) Clouds (Universita' della Georgia) che consente la replica degli oggetti