2011-11-01 27 views
5

que quieren:SQL seleccione Filas en una tabla y actualizar las mismas filas

  1. Seleccionar N filas de una tabla a la transformación siempre bandera = 0
  2. hacer algún trabajo en una segunda tabla usando los valores de éstos N filas
  3. Actualizar estos N filas y con una bandera = 1

que tienen procesos paralelos que hacen esto mismo trabajo juntos, y quieren asegurarse de que todos manos a la obra en filas únicas. ¿Cómo me aseguro?

Respuesta

5

Supongo que se está ejecutando en SQL Server (debido a la etiqueta), de lo contrario, mi respuesta no es aplicable. El bloqueo solo no es suficiente. Si utiliza el bloqueo de registros de la base de datos, el servidor SqL bloqueará otros procesos que intenten acceder a la fila bloqueada y, de hecho, manejará solo una fila a la vez. La solución para usted es combinar el bloqueo de filas con la sugerencia de READPAST para que las filas bloqueadas por alguien más se omitan. Esto es lo que cada proceso debe hacer:

  1. seleccione siguiente fila desbloqueado para su procesamiento y bloquearla
  2. haga el trabajo
  3. actualización de la transacción fila y al final

select top 1 id, ... from TheTable with (updlock, readpast) where flag = 0

//do the work now

update TheTable set flag = 1 where id=<previously retrieved id>

Lo bueno aquí es que la operación de seleccionar la siguiente fila desbloqueada y bloquearla es atómica, por lo que garantiza que nadie más podrá seleccionar la misma fila.

+0

LECTURA DE READPAST hace el truco, un buen artículo http://www.mssqltips.com/sqlservertip/1257/processing-data-queues-in-sql-server-with-readpast-and-updlock/ – newbie

+0

Con SQL 2008 , puede usar la cláusula OUTPUT con la sugerencia de LECTURA en la consulta para combinar la operación de cola en una sola instrucción.http: //www.sqlservercentral.com/articles/Queue+processing/69653/ – newbie

+0

@newbie Sí, puede usar salida para bloquear y recuperar mensajes y marcarlos procesados ​​en una sola consulta. Pero he estado comparando el rendimiento para el procesamiento de mensajes únicos y no hay ganancia en comparación con dos consultas (seleccione primero y luego actualice). En realidad, el rendimiento de subprocesos múltiples fue un poco menor cuando se usaba la consulta SALIDA. Tal vez en el procesamiento por lotes la cláusula de salida sea más rápida, pero para los mensajes individuales no lo es. – nightwatch

0

Una forma es tener un programa maestro que distribuya segmentos a los hilos hijo.

Otra forma es bloquear la tabla, obtener CEIL(N/#processes) filas donde flag = 0, actualizar el indicador a 2, luego suelte el bloqueo. Luego, el próximo proceso continuará desde que obtuvo el bloqueo, y dado que flag = 2 no obtendrá esas filas.

Tiene dos formas de bloquear la tabla: puede bloquear todo o SELECCIONAR ... PARA ACTUALIZAR con un límite (para no obtener demasiadas filas). Ver: SELECT FOR UPDATE with SQL Server

Incluso mejor que establecer el indicador en 2 es establecer el indicador en el id_proceso. Entonces, todo lo que tiene que hacer es actualizar todas las filas para distribuir los números, luego dejar que el proceso entre en funcionamiento, cada uno revisando solo sus propias filas.

Cuestiones relacionadas