8

Bastante simple pregunta. En SQL 2008, si tengo un procedimiento almacenado (ver a continuación), ¿corro el riesgo de una condición de carrera entre las dos primeras declaraciones o el procedimiento almacenado bloquea las cosas que toca como lo hacen las transacciones?¿Los procedimientos almacenados bloquean las tablas/filas?

ALTER PROCEDURE [dbo].[usp_SetAssignedTo] 
    -- Add the parameters for the stored procedure here 
    @Server varchar(50), 
    @User varchar(50), 
    @UserPool varchar(50) 
AS 
BEGIN 
    SET NOCOUNT ON; 
    Declare @ServerUser varchar(50) 

    -- Find a Free record 
    SELECT top 1 @ServerUser = UserName 
    from ServerLoginUsers 
    where AssignedTo is null and [TsServer] = @Server 

    --Set the free record to the user 
    Update ServerLoginUsers 
    set AssignedTo = @User, AssignedToDate = getdate(), SourcePool = @UserPool 
    where [TsServer] = @Server and UserName = @ServerUser 

    --report record back if it was updated. Null if it was not available. 
    select * 
    from ServerLoginUsers 
    where [TsServer] = @Server 
     and UserName = @ServerUser 
     and AssignedTo = @User 
END 

Respuesta

3

Puede obtener una condición de carrera.

Se puede hacer en una declaración:

  • Puede asignar en una actualización
  • Las sugerencias de bloqueo permiten otro proceso para omitir esta fila
  • la cláusula OUTPUT devuelve los datos de la persona que llama

Prueba esto ... (edit: holdlock eliminado)

Update TOP (1) ServerLoginUsers WITH (ROWLOCK, READPAST) 
OUTPUT INSERTED.* 
SET 
    AssignedTo = @User, AssignedToDate = getdate(), SourcePool = @UserPool 
WHERE 
    AssignedTo is null and [TsServer] = @Server -- not needed -> and UserName = @ServerUser 

Si no es así, es posible que necesite una por separado seleccione

Update TOP (1) ServerLoginUsers WITH (ROWLOCK, READPAST) 
SET 
    -- yes, assign in an update 
    @ServerUser = UserName, 
    -- write 
    AssignedTo = @User, AssignedToDate = getdate(), SourcePool = @UserPool 
OUTPUT INSERTED.* 
WHERE 
    AssignedTo is null and [TsServer] = @Server -- not needed -> and UserName = @ServerUser 

SELECT ... 

ver este favor para más: SQL Server Process Queue Race Condition

+0

instrucción de salida debe ser puesto después de que el conjunto de la sintaxis correcta –

+0

utilicé el primer ejemplo pero obtuve el error 'Solo se puede especificar el bloqueo READPAST en los niveles de aislamiento READ COMMITTED o REPEATABLE READ. cuando lo ejecuté. –

+0

Ah OK, soltar HOLDLOCK luego – gbn

Cuestiones relacionadas