Básicamente, está describiendo un flujo de trabajo clásico basado en colas y debería considerar usar un cola .
En aras de la discusión, así es como logras lo que deseas:
- reclamar recurso específico:
SELECT ... FROM resources WITH (UPDLOCK, ROWLOCK) WHERE key = @key
. Se bloqueará si el recurso ya está reclamado. Utilice los tiempos de espera de bloqueo para devolver una excepción si el recurso ya se ha reclamado.key
debe ser indexado y único. - siguiente recurso disponible:
SELECT ... FROM resources WITH (UPDLOCK, ROWLOCK, READPAST) ORDER BY <accessorder>
. Debe definir un orden por para expresar la preferencia de los recursos (más antiguos, de mayor prioridad, etc.) - liberar un recurso reclamado:
COMMIT
su transacción.
La esencia del problema es usar las sugerencias de bloqueo correctas, y este tipo de problema requiere sugerencias de bloqueo explícitas para resolverlo. UPDLOCK actuará como un bloqueo de 'reclamo'. ROWLOCK crea la granularidad correcta evitando que el servidor se 'optimice' a un bloqueo de página. READPAST le permite omitir los recursos reclamados. Si coloca UPDLOCK en las filas, bloqueará la fila y le permitirá actualizarla más tarde, pero evitará otras operaciones, como los SELECT ordinarios de lectura confirmada, que se bloquearán en la fila bloqueada. Sin embargo, la idea es que vas a ACTUALIZAR la fila de todos modos, lo que colocará un bloqueo X inevitable. Si desea mantener la tabla más disponible, puede usar bloqueos de aplicaciones en cambio, pero es significativamente más difícil de lograr correctamente. Deberá solicitar un bloqueo de aplicación en un descriptor de cadena del recurso, como el valor clave, o un CHECKSUM
de la clave o es %%LOCKRES%%
valor. Los bloqueos de aplicaciones le permiten separar el alcance de la 'reclamación' de una transacción solicitando el bloqueo de la aplicación en el alcance de la 'sesión', pero luego debe liberar la reclamación manualmente (los bloqueos de aplicaciones con alcance de 'transacción' se liberan en el momento de la confirmación) . Sin embargo, ten cuidado, hay mil formas de pegarte un tiro en el pie con los bloqueos de aplicaciones.