Pregunta

El problema que tengo es la siguiente:

Tengo una tabla (sólo un ejemplo) con los siguientes campos:

ID int
Value int

Tengo un método llamado IncreaseByFive (), que hace lo siguiente:

method IncreaseByFive(int ID)
{    
    int value = GetValueFromDB(ID);
    value = value + 5;
    SaveValueToDB(value, ID);    
}

Lo que quiero evitar es la siguiente situación:

  1. El usuario A llama al método y obtiene el valor (actualmente 5)
  2. El usuario llama al método B y obtiene el valor (actualmente 5)
  3. El usuario A aumenta el valor por 5 (ahora 10)
  4. Usuario B aumenta el valor por 5 (ahora 10)
  5. El usuario A ahorra valor (10)
  6. Usuario B ahorra valor (10)

Ahora, el registro tiene un valor de 10 cuando debería haber sido 15.

Lo que quiero a la fuerza es la siguiente:

  1. El usuario A llama al método y obtiene el valor (actualmente 5)
  2. El usuario llama al método B, pero tiene que esperar porque A ya lo llamaron. (Dibs!)
  3. El usuario A aumenta el valor (ahora 10)
  4. El usuario B está a la espera
  5. Un usuario guarda el valor (valor de registro tiene 10)
  6. Usuario B ahora puede leer el valor (10)
  7. Usuario B aumenta el valor (15)
  8. El usuario B guarda el valor

Ahora, el registro tiene un valor de 15, que es el resultado que estoy buscando.

He resuelto este problema en el pasado el uso de una clase estática y poner un bloqueo en un objeto estático creado dentro del constructor de esa clase, por lo tanto canalizando todo el trabajo a través de un método estático, lo que obliga a otras llamadas que esperar en fila . Estoy sin embargo miedo de que esto no es escalable.

También creo que el nivel más alto de aislamiento (serializable) para una transacción no va a hacer el truco, ya sea porque va a permitir que la lectura en el paso 2 del ejemplo anterior no deseada.

supongo que otra solución sería crear mi propia tabla de bloqueo y registrar los bloqueos de allí, pero que parece que no debería ser necesario.

Estoy desarrollando este proyecto con C # (3.5) y el servidor SQL 2008.

¿Qué piensa la mente de la colmena?

¿Fue útil?

Solución

Tal vez soy más underthinking esto, pero no habría que acaba de envolver todo el bloque lógico ..

  • valor leído
  • valor de escribir

en una transacción de base de datos de la href="http://technet.microsoft.com/en-us/library/ms173763.aspx" rel="nofollow noreferrer"> nivel apropiado

SET TRANSACTION ISOLATION LEVEL
    { READ UNCOMMITTED
    | READ COMMITTED
    | REPEATABLE READ
    | SNAPSHOT
    | SERIALIZABLE
    }
[ ; ]
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top