多个人可以同时更新SQL Server中的相同记录吗?

时间:2015-05-13 16:19:44

标签: sql-server

我有一个类似于下面的SQL语句。基本上,如果项目处于未分配状态,它会将项目分配给具有指定状态的用户。如果两个人在同一时间调用此语句,他们是否可以使用其用户ID更新相同的记录,或者数据库是否会自动锁定记录,因为它是更新?我目前没有在任何类型的交易中运行该声明。我是否需要确保只有一个人可以将行设置为已分配?

Update top (1) QUE.[Queue] set
                QueueStatusId = 2 -- set to assigned
                , QueueAssignedUserId = @QueueAssignedUserId
                , QueueAssignedDateTimeUTC = getutcdate()
from QUE.[Queue] updateq
where updateq.QueueStatusId = 1 -- only select unassigned

更新

这是我的代码的稍微更近的表示。您可以看到我实际上没有where子句,以确保我只获得状态为1的项目。相反,我加入到表中,考虑到状态和分配到期日期。是否可以对该内部联接查询进行快照,以便多个用户加入数据的脏副本?

Update top (1) QUE.[Queue] set
                QueueStatusId = 2 -- set to assigned
                , QueueAssignedUserId = @QueueAssignedUserId
                , QueueAssignedDateTimeUTC = getutcdate()
from QUE.[Queue] updateq
inner join (select * from QUE.[Queue] 
    where QueueStatusId = 1 
        or (QueueStatusId = 2 and QueueAssignmentExpirationDateTimeUTC > getutcdate()) qStatuses 
    on qStatuses.QueueId = updateq.QueueId

1 个答案:

答案 0 :(得分:3)

每个语句都包含在一个隐式事务中。因此,如果语句几乎同时执行了两次...... SQL Server将选择其中一个,执行更新,然后第二次更新执行将无法选择该记录,因为它会有{{1在第一个查询中更改了字段。

然而,如果未在显式事务中包装,则第二个版本中的子查询可能会导致竞争条件。有两个用户可能在任何一个更新之前都运行子查询,然后两个用户都尝试更新相同的记录。您可以在不使用子查询的情况下构建更新,并消除竞争条件的可能性:

QueueStatusId

此问题还包括一些有用的信息和链接: Transaction isolation levels and subqueries