sql >> Base de Datos >  >> RDS >> Sqlserver

Acceso exclusivo mutuo TSQL en un procedimiento almacenado

SERIALIZABLE es un nivel de aislamiento para el bloqueo, no un semáforo .

No funcionará en este caso, todo lo que hará es persistir un bloqueo de lectura hasta el final del TXN que no impide otro proceso en la lectura del código.

Debe usar sp_getapplock en modo Transacción. Puede configurarlo para que espere, bombardee inmediatamente, etc.:depende de usted

Esto se basa en mi plantilla de ¿Procedimientos almacenados anidados que contienen el patrón TRY CATCH ROLLBACK?

ALTER PROCEDURE get_code 
AS
SET XACT_ABORT, NOCOUNT ON

DECLARE @starttrancount int, @result int;

BEGIN TRY
    SELECT @starttrancount = @@TRANCOUNT

    IF @starttrancount = 0 BEGIN TRANSACTION

    EXEC @result = sp_getapplock 'get_code', 'Exclusive', 'Transaction', 0 
    IF @result < 0
        RAISERROR('INFO: One at a time please`!', 16, 1);

    [...Perform work...]


    IF @starttrancount = 0 
        COMMIT TRANSACTION
    ELSE
        EXEC sp_releaseapplock 'get_code';
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 AND @starttrancount = 0 
        ROLLBACK TRANSACTION
    RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc]
END CATCH
GO