Condividi tramite


Concorrenza ottimistica

La concorrenza ottimistica deriva il nome dal presupposto ottimistico che le collisioni tra transazioni si verifichino raramente. si dice che una collisione si è verificata quando un'altra transazione aggiorna o elimina una riga di dati tra il momento in cui viene letta dalla transazione corrente e quello in cui viene aggiornata o eliminata. È l'opposto della concorrenza pessimistica, o del blocco, in cui lo sviluppatore di applicazioni ritiene che tali collisioni siano comuni.

Nella concorrenza ottimistica, una riga viene lasciata sbloccata fino all'aggiornamento o all'eliminazione. A questo punto, la riga viene riletta e controllata per verificare se è stata modificata dopo l'ultima lettura. Se la riga è stata modificata, l'aggiornamento o l'eliminazione ha esito negativo e bisogna riprovare.

Per determinare se una riga è stata modificata, la sua nuova versione viene confrontata con una versione in cache della riga stessa. Questo controllo può essere basato sulla versione della riga, ad esempio la colonna data e ora di SQL Server, o sui valori di ogni colonna nella riga. Molti DBMS non supportano le versioni della riga.

La concorrenza ottimistica può essere implementata dall'origine dati o dall'applicazione. In entrambi i casi, l'applicazione dovrebbe usare un basso livello di isolamento della transazione, ad esempio Read Committed; l'uso di un livello superiore nega l'aumento della concorrenza ottenuta usando la concorrenza ottimistica.

Se la concorrenza ottimistica viene implementata dall'origine dati, l'applicazione imposta l'attributo dell'istruzione SQL_ATTR_CONCURRENCY su SQL_CONCUR_ROWVER o SQL_CONCUR_VALUES. Per aggiornare o eliminare una riga, esegue un'istruzione di eliminazione o aggiornamento posizionato o chiama SQLSetPos esattamente come in un caso di concorrenza pessimistica. Il driver o l'origine dati restituisce SQLSTATE 01001 (conflitto dell'operazione cursore) se l'aggiornamento o l'eliminazione non riesce a causa di un conflitto.

Se l'applicazione stessa implementa la concorrenza ottimistica, imposta l'attributo dell'istruzione SQL_ATTR_CONCURRENCY su SQL_CONCUR_READ_ONLY per leggere una riga. Se confronta le versioni della riga e non conosce la colonna della versione della riga, chiama SQLSpecialColumns con l'opzione SQL_ROWVER per determinare il nome di questa colonna.

L'applicazione aggiorna o elimina la riga aumentando la concorrenza a SQL_CONCUR_LOCK (per ottenere l'accesso in scrittura alla riga) ed eseguendo un'istruzione UPDATE o DELETE con una clausola WHERE che specifica la versione o i valori della riga quando l'applicazione la legge. Se la riga è stata modificata da allora, l'istruzione avrà esito negativo. Se la clausola WHERE non identifica in modo univoco la riga, l'istruzione potrebbe anche aggiornare o eliminare altre righe. Le versioni della riga identificano sempre in modo univoco le righe, ma i valori di riga identificano in modo univoco le righe solo se includono la chiave primaria.