【问题标题】:Application lock for Stored Procedure存储过程的应用程序锁
【发布时间】:2020-12-18 07:51:38
【问题描述】:

我有一个可以安排工作的应用程序。我对作业的控制有限。该作业执行存储过程。有什么办法可以锁定存储过程,使作业不能同时执行这个存储过程? 我想检查一下 SQL server 是否提供了一些东西。

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    您可以使用sp_getapplock 获取“自定义”或“应用程序”锁,并使用sp_releaseapplock 释放它。

    辅助函数是:

    • APPLOCK_TEST - 返回有关是否可以在特定应用程序资源上授予锁定的信息
    • APPLOCK_MODE - 此函数返回锁定所有者在特定应用程序资源上持有的锁定模式

    请注意,sp_getapplock 不会锁定数据库中的任何表,它只会创建一个自定义命名锁。应用程序可以使用此功能来处理并发。

    示例:

    在 SSMS 中打开 2 个查询窗口,并在 1 分钟内运行以下代码。

    DECLARE
            @LockResult         INT
        ,   @LockErrorMessage   NVARCHAR(MAX) = N'Failed to acquire lock.'
    ;
    
    EXEC @LockResult = sys.sp_getapplock
            @Resource       = N'TestResource'
        ,   @LockMode       = N'Exclusive'
        ,   @LockOwner      = N'Session'
        ,   @LockTimeout    = 60000           /* 1 minute */
        ,   @DbPrincipal    = N'public'
    ;
    
    IF (@LockResult < 0) BEGIN
        THROW 50000, @LockErrorMessage, 0;
    END
    ELSE
    BEGIN
        SELECT 1 AS test;
    
        /* EXEC MyControlledSP */
        /* For demonstration purposes only! */
        WAITFOR DELAY '00:02:00';
    
        /* The work is done, release the lock */
        EXEC sys.sp_releaseapplock
                @Resource       = N'TestResource'
            ,   @LockOwner      = N'Session'
            ,   @DbPrincipal    = N'public'
        ;
    END;
    

    您可以在 SP 本身中获取锁并仅在成功获取锁时运行它的主体,因此使用该存储过程的任何应用程序/进程也将隐式检查锁,您不会依赖于拥有所有应用程序/处理调整。

    不要忘记释放锁,尤其是当所有者是会话时。关闭连接(例如关闭查询窗口)会自动释放锁。


    如果计划任务是 SQL Server 代理作业,您不必执行自定义锁定,因为一个作业只能运行一次,并且当有正在运行的实例时,代理不会启动第二个(即使日程安排会这样说)。

    【讨论】:

    • 如何让 sp_getapplock 获取当前存储过程的锁?我不想为一张桌子这样做。
    • @RahulSingh 请阅读程序文档。它没有锁定任何表。
    • 让我重新表述我的问题。我想为整个存储过程获取锁。有没有类似 sp_getapplock resourceName = 'my_sproc'
    • 您不能锁定存储过程。您只能锁定一个资源。但是当两个应用程序试图锁定同一个资源时,一个会成功,另一个将不得不等待。
    • @RahulSingh 您可以将资源名称(只是任意文本)设置为您的存储过程名称 - 更容易理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多