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:

  1. L'utente A chiama il metodo e ottiene il valore (attualmente 5)
  2. L'utente B chiama il metodo e ottiene il valore (attualmente 5)
  3. L'utente A aumenta il valore da 5 (ora 10)
  4. L'utente B aumenta il valore da 5 (ora 10)
  5. Un utente salva il valore (10)
  6. 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:

  1. L'utente A chiama il metodo e ottiene il valore (attualmente 5)
  2. L'utente B chiama il metodo, ma deve aspettare perché A già lo chiamavano. (Dibs!)
  3. L'utente A aumenta il valore (ora 10)
  4. L'utente B è ancora in attesa
  5. L'utente A salva il valore (record ha valore di 10)
  6. L'utente B può ora leggere il valore (10)
  7. L'utente B aumenta il valore (15)
  8. 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?

È stato utile?

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
    }
[ ; ]
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top