2010-02-19 4 views
7

Básicamente tengo una aplicación que tiene, digamos 5 hilos, que cada uno lee de una tabla. La consulta es simplemente SELECCIONAR TOP 1 * de la tabla, pero quiero aplicar un bloqueo para que el siguiente hilo seleccione el siguiente registro de la tabla y no el bloqueado. Cuando la aplicación haya terminado su tarea, actualizará el registro bloqueado y liberará el bloqueo y repetirá el proceso nuevamente. es posible?Cerraduras de fila - utilizándolas manualmente

+1

hice un supuesto esto es SQL Server - es así? – AdaTheDev

Respuesta

8

El tipo de enfoque que recomendaría es tener un campo en el registro que indique si el registro se está procesando o no. A continuación, poner en práctica un procedimiento almacenado "leer a continuación de la cola" que hace lo siguiente, para asegurar que no 2 procesos recoger el mismo registro:

BEGIN TRANSACTION 

-- Find the next available record that's not already being processed. 
-- The combination of UPDLOCK and READPAST hints makes sure 2 processes don't 
-- grab the same record, and that processes don't block each other. 
SELECT TOP 1 @ID = ID 
FROM YourTable WITH (UPDLOCK, READPAST) 
WHERE BeingProcessed = 0 

-- If we've found a record, set it's status to "being processed" 
IF (@ID IS NOT NULL) 
    UPDATE YourTable SET BeingProcessed = 1 WHERE ID = @ID 

COMMIT TRANSACTION 

-- Finally return the record we've picked up 
IF (@ID IS NOT NULL) 
    SELECT * FROM YourTable WHERE ID = @ID 

Para obtener más información sobre estas sugerencias de tabla, consulte MSDN

+0

Gracias por la respuesta rápida. ¿Tendría que hacer la declaración de actualización de inmediato? Si realicé la transacción después de SELECT, ¿eso dejaría el bloqueo en su lugar? –

+0

No, la cerradura no permanecería en su lugar. – AdaTheDev

+0

Sí, esto es SQL Server, 2008 para ser precisos. Entonces, ¿tendría que iniciar una transacción dentro de la aplicación, seleccionar el registro, hacer el procesamiento necesario en la aplicación y actualizar el registro y confirmar la transacción para mantener la fila bloqueada? –

0

Service Broker Queues en el servidor Sql se diseñó específicamente para abordar este escenario.

Tener que bloquear tablas y filas parece una forma inversa de lograr esta funcionalidad.

+1

Ver [¿POR QUÉ NO USAR COLAS CONSTRUIDAS?] (Http://rusanu.com/2010/03/26/using-tables-as-queues/) –

+0

Los argumentos son bastante buenos, pero 1) la afirmación de que son difíciles de usar es tonto, simplemente no lo son. Podría ser más fácil, pero ciertamente no es difícil. 2) Estoy de acuerdo, sería bueno tener una estructura flexible. 3) La falta de mantenimiento solo sería un problema real en casos excepcionales ~ 3,000 + msg/s. Yo diría que en ese caso se trata más de un problema de diseño que del fracaso de la tecnología. Además, la solución sugerida anteriormente no eludirá el problema de la fragmentación, pero sería más fácil de resolver. –

+1

El autor del artículo fue uno de los desarrolladores del broker de servicios, por lo que si recomiendan usar las tablas como colas antes que como intermediario de servicios, me inclino a tomarlo como valor nominal. –

Cuestiones relacionadas