【问题标题】:Do stored procedures lock tables/rows?存储过程会锁定表/行吗?
【发布时间】:2010-10-01 16:49:26
【问题描述】:

很简单的问题。在 SQL 2008 中,如果我有一个存储过程(见下文),我是否会冒前两个语句之间出现竞争条件的风险,或者存储过程是否会像事务一样锁定它所触及的事物?

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

【问题讨论】:

    标签: sql-server tsql sql-server-2008 stored-procedures concurrency


    【解决方案1】:

    你可以得到一个竞争条件。

    可以在一个语句中完成:

    • 您可以在 UPDATE 中分配
    • 锁定提示允许另一个进程跳过此行
    • OUTPUT 子句将数据返回给调用者

    试试这个...(编辑:holdlock 已移除)

    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
    

    如果没有,您可能需要单独选择

    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 ...
    

    更多信息请查看:SQL Server Process Queue Race Condition

    【讨论】:

    • 输出语句需要放在集合之后才能正确语法
    • 我使用了您的第一个示例,但运行时出现错误You can only specify the READPAST lock in the READ COMMITTED or REPEATABLE READ isolation levels.
    • 嗯,好的,然后放下 HOLDLOCK
    猜你喜欢
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 2019-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多