Chiamando Dibs su una riga della tabella
-
22-08-2019 - |
Domanda
Il problema che ho è questa:
Ho una tabella (solo un esempio) con i seguenti campi:
ID int
Value int
Ho un metodo chiamato IncreaseByFive (), che esegue le seguenti operazioni:
method IncreaseByFive(int ID)
{
int value = GetValueFromDB(ID);
value = value + 5;
SaveValueToDB(value, ID);
}
Quello che voglio evitare è la seguente situazione:
- L'utente A chiama il metodo e ottiene il valore (attualmente 5)
- L'utente B chiama il metodo e ottiene il valore (attualmente 5)
- L'utente A aumenta il valore da 5 (ora 10)
- L'utente B aumenta il valore da 5 (ora 10)
- Un utente salva il valore (10)
- L'utente B consente di risparmiare il valore (10)
Ora il record ha un valore di 10, quando avrebbe dovuto essere 15.
Quello che voglio forzare è la seguente:
- L'utente A chiama il metodo e ottiene il valore (attualmente 5)
- L'utente B chiama il metodo, ma deve aspettare perché A già lo chiamavano. (Dibs!)
- L'utente A aumenta il valore (ora 10)
- L'utente B è ancora in attesa
- L'utente A salva il valore (record ha valore di 10)
- L'utente B può ora leggere il valore (10)
- L'utente B aumenta il valore (15)
- L'utente B salva il valore
Ora il record ha un valore di 15, che è il risultato che sto cercando.
Ho risolto questo problema in passato utilizzando una classe statica e mettere un blocco su un oggetto statico creato all'interno del costruttore di questa classe, quindi incanalando tutto il lavoro attraverso un metodo statico, che costringe altre chiamate ad attendere in linea . Temo, tuttavia, che questo non è scalabile.
Penso anche che il livello più alto di isolamento (serializzabile) per una transazione non farà il trucco sia perché permetterà la lettura al punto 2 dell'esempio indesiderati sopra.
Credo che un'altra soluzione potrebbe essere quella di creare la mia tabella di blocco e registrare le serrature là, ma che sembra non dovrebbe essere necessario.
sto sviluppando questo progetto con C # (3,5) e il server SQL 2008.
Che cosa fa la mente alveare pensi?
Soluzione
Forse sto sopra underthinking questo, ma non ti basta avvolgere l'intero blocco logico ..
- valore letto
- valore di scrittura
in una transazione di database del href="http://technet.microsoft.com/en-us/library/ms173763.aspx" rel="nofollow noreferrer"> livello appropriato
SET TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED
| READ COMMITTED
| REPEATABLE READ
| SNAPSHOT
| SERIALIZABLE
}
[ ; ]