none
Evitar que multiples consultas a la base de datos al mismo tiempo devuelvan el mismo row RRS feed

  • Pregunta

  • La situación es la siguiente cuento con una tabla cliente el cual debe de ser procesado (cualquier acción sobre este) una vez, el tema es el siguiente el trabajo se realiza en paralelo y desde múltiples instancias, para una mayor velocidad, por tanto la tabla cliente tiene un campo estado el cual 0 libre y 1 siendo procesado. ¿Como pudiera bloquear la tabla, o no se de que otra manera pudiera garantizar, que el mismo cliente no acabe siendo procesado dos veces por instancias diferentes?. Se da el caso de que antes de que el estado cambie de 0 a 1, ya otra instancia obtuvo el mismo cliente.
    martes, 23 de julio de 2019 4:49

Respuestas

  • Gracias por la respuesta.

    y que me aconsejas?. Pongo esa lógica dentro de un Stored Procedure y en vez de ejecutar mi consulta desde C# usando(ADO.net y Linq) invoco al "getClient_SP" (por ejemplo) que devuelva una fila de la tabla garantizando la asignación única del cliente?. Algo como esto:

    BEGIN TRANSACTION

    //obtener la primera fila que cumpla la condición de que el estado sea 0

    //Hacer un update del estado de 0 a 1

    COMMIT TRANSACTION



    martes, 23 de julio de 2019 6:12

Todas las respuestas

  • Para eso se usan las transacciones. Primero inicias transacción, y entonces comienzas a hacer cambios en la tabla, por ejemplo, cambias el estado de 0 a 1. Al hacer eso, el registro queda bloqueado, y si algún otro cliente intenta acceder a él se quedará momentáneamente congelado hasta que el bloqueo se quite. Cuando termines de hacer todos los cambios, haces un Commit de la transacción, y eso quita todos los bloqueos que hubieran sido aplicados por la transacción.
    martes, 23 de julio de 2019 5:52
  • Gracias por la respuesta.

    y que me aconsejas?. Pongo esa lógica dentro de un Stored Procedure y en vez de ejecutar mi consulta desde C# usando(ADO.net y Linq) invoco al "getClient_SP" (por ejemplo) que devuelva una fila de la tabla garantizando la asignación única del cliente?. Algo como esto:

    BEGIN TRANSACTION

    //obtener la primera fila que cumpla la condición de que el estado sea 0

    //Hacer un update del estado de 0 a 1

    COMMIT TRANSACTION



    martes, 23 de julio de 2019 6:12
  • Puedes hacerlo desde un SP como propones, pero no es necesario. Si ejecutas la misma transacción desde el lado cliente también funciona igual.

    Te recomiendo hacer la lectura y el update en una sola operación. De lo contrario, dos clientes podrían obtener la misma primera fila, ya que la operación de lectura no bloquea contra otra lectura. Necesitas una escritura para bloquear contra otras escrituras. Por ejemplo:

    BEGIN TRANSACTION

    UPDATE laTabla SET estado=1 WHERE clavePrimaria IN (select top 1 clavePrimaria from laTabla where estado=0 order by loQueSea)

    COMMIT TRANSACTION

    Si únicamente vas a ejecutar esa sentencia, no es necesario que agregues la transacción porque una sentencia aislada por sí sola ya se ejecuta dentro de una transacción.

    Si necesitas saber cuál ha sido el registro seleccionado, puedes agregar una cláusula OUTPUT en la sentencia UPDATE, no es necesario agregar otra sentencia separada.

    martes, 23 de julio de 2019 8:20