Quando si affrontano i conflitti, sono disponibili due opzioni:
- Puoi provare a evitare il conflitto, ed è quello che fa il Pessimistic Locking.
- In alternativa, è possibile consentire il verificarsi del conflitto, ma è necessario rilevarlo al momento del commit delle transazioni, ed è ciò che fa il blocco ottimistico.
Consideriamo ora la seguente anomalia di Lost Update :
L'anomalia di Lost Update può verificarsi nel livello di isolamento Read Committed .
Nel diagramma sopra possiamo vedere che Alice crede di poterne ritirare 40 da lei, account
ma non si rende conto che Bob ha appena cambiato il saldo del conto, e ora ne rimangono solo 20 in questo conto.
Blocco pessimistico
Il blocco pessimistico raggiunge questo obiettivo prendendo un blocco condiviso o di lettura sull'account in modo da impedire a Bob di modificare l'account.
Nel diagramma sopra, sia Alice che Bob acquisiranno un blocco di lettura sulla account
riga della tabella che entrambi gli utenti hanno letto. Il database acquisisce questi blocchi su SQL Server quando si utilizza Lettura ripetibile o Serializable.
Poiché sia Alice che Bob hanno letto il account
valore PK di 1
, nessuno dei due può modificarlo fino a quando un utente non rilascia il blocco di lettura. Questo perché un'operazione di scrittura richiede un'acquisizione di blocchi di scrittura / esclusivi e i blocchi condivisi / di lettura impediscono i blocchi di scrittura / esclusivi.
Solo dopo che Alice ha eseguito la transazione e il blocco di lettura è stato rilasciato sulla account
riga, Bob UPDATE
riprenderà e applicherà la modifica. Fino a quando Alice non rilascia il blocco di lettura, l'UPDATE di Bob si blocca.
Per maggiori dettagli su come i framework di accesso ai dati utilizzano il supporto di blocco pessimistico del database sottostante, consulta questo articolo .
Blocco ottimistico
Il blocco ottimistico consente che si verifichi il conflitto ma lo rileva quando si applica AGGIORNAMENTO di Alice quando la versione è cambiata.
Questa volta, abbiamo una version
colonna aggiuntiva . La version
colonna viene incrementata ogni volta che viene eseguito un UPDATE o DELETE e viene anche utilizzata nella clausola WHERE delle istruzioni UPDATE e DELETE. Perché ciò funzioni, dobbiamo emettere SELECT e leggere l'attuale version
prima di eseguire UPDATE o DELETE, altrimenti, non sapremmo quale valore di versione passare alla clausola WHERE o da incrementare.
Per maggiori dettagli su come i framework di accesso ai dati implementano il blocco ottimistico, leggi questo articolo .
Transazioni a livello di applicazione
I sistemi di database relazionali sono emersi alla fine degli anni '70, all'inizio degli anni '80, quando un client si connetteva in genere a un mainframe tramite un terminale. Ecco perché vediamo ancora che i sistemi di database definiscono termini come l'impostazione SESSIONE.
Al giorno d'oggi, su Internet, non eseguiamo più letture e scritture nel contesto della stessa transazione di database e ACID non è più sufficiente.
Ad esempio, considerare il seguente caso d'uso:
Senza un blocco ottimistico, non è possibile che questo aggiornamento perduto venga rilevato anche se le transazioni del database utilizzano Serializable. Questo perché letture e scritture vengono eseguite in richieste HTTP separate, quindi su diverse transazioni del database.
Pertanto, il blocco ottimistico può aiutarti a prevenire gli aggiornamenti persi anche quando utilizzi transazioni a livello di applicazione che incorporano anche il tempo di riflessione dell'utente.
Per ulteriori dettagli sulle transazioni logiche o a livello di applicazione, consulta questo articolo .
Conclusione
Il blocco ottimistico è una tecnica molto utile e funziona perfettamente anche quando si utilizzano livelli di isolamento meno rigorosi, come Read Committed, o quando le letture e le scritture vengono eseguite nelle successive transazioni del database.
L'aspetto negativo del blocco ottimistico è che il rollback verrà attivato dal framework di accesso ai dati al momento della cattura di un OptimisticLockException
, quindi perdendo tutto il lavoro svolto in precedenza dalla transazione attualmente in esecuzione.
Più contesa, più conflitti e maggiore è la possibilità di interrompere le transazioni. I rollback possono essere costosi per il sistema di database in quanto devono ripristinare tutte le modifiche in sospeso che potrebbero coinvolgere sia le righe della tabella che i record dell'indice.
Per questo motivo, il blocco pessimistico potrebbe essere adatto quando si verificano frequentemente conflitti, poiché riduce la possibilità di ripristinare le transazioni.