将使用SQL Server';是否在子查询中更新并锁定表?
我正在使用SQL Server,有一个可以通过多线程访问的查询。为了从每个线程返回唯一的行,我有以下查询将使用SQL Server';是否在子查询中更新并锁定表?,sql,sql-server,sql-update,Sql,Sql Server,Sql Update,我正在使用SQL Server,有一个可以通过多线程访问的查询。为了从每个线程返回唯一的行,我有以下查询 DECLARE @Guid uniqueidentifier = NEWID(); -- update first to lock what to get UPDATE [olp].[VendorTaskQueue] SET VendorTaskStatusId = 20 -- processing , [Guid] = @Guid WHERE VendorTaskQueu
DECLARE @Guid uniqueidentifier = NEWID();
-- update first to lock what to get
UPDATE [olp].[VendorTaskQueue]
SET VendorTaskStatusId = 20 -- processing
, [Guid] = @Guid
WHERE VendorTaskQueueId IN (
SELECT TOP (@BatchSize) VendorTaskQueueId
FROM [olp].[VendorTaskQueue]
WHERE VendorTaskId = @VendorTaskId
AND VendorTaskStatusId = 10
AND [Guid] IS NULL
ORDER BY VendorTaskQueueId
)
-- only need to return these fields
SELECT [VendorTaskQueueId]
,[MessageQueueId]
FROM [olp].[VendorTaskQueue]
WHERE [Guid] = @Guid
AND VendorTaskStatusId = 20
为了更新@BatchSize行,有一个WHERE子句。在上面的例子中,SELECT子查询使用同一个表,因此我假设当多线程访问它时,它不会引起任何问题。但是,如果此子查询使用另一个表,该怎么办:
DECLARE @Guid uniqueidentifier = NEWID();
-- update first to lock what to get
UPDATE [olp].[VendorTaskQueue]
SET VendorTaskStatusId = 20 -- processing
, [Guid] = @Guid
WHERE VendorTaskQueueId IN (
SELECT TOP (@BatchSize) VendorTaskQueueId
FROM [olp].[*** Another table]
WHERE VendorTaskId = @VendorTaskId
AND VendorTaskStatusId = 10
AND [Guid] IS NULL
ORDER BY VendorTaskQueueId
)
......
我的问题是:既然是更新,SQL会锁定[VendorTaskQueue]和[Other table]吗?或者,我们需要显式地锁定[另一个表]
谢谢SQL Server默认情况下使用行级锁定-它不会锁定表-只锁定您要更新的行。只有在单个事务中有超过5000个并发
UPDATE
操作时,此选项才会更改-然后SQL Server将执行锁升级并锁定整个表,这样它将锁定[VendorTaskQueue],但不会锁定[另一个表]?否-它将只锁定[VendorTaskQueue]中的一些行。
(那些与UPDATE
中的WHERE
子句匹配的表)-对于读取提交事务隔离级别(默认为“其他表”),它不会锁定整个表(除非-如上所述-您一次更新的行数超过5000行-然后它才会锁定整个表)将仅在执行期间具有共享锁,并且在完成选择后,即使尚未提交更新,共享锁也将被释放。因此,我们需要锁定“另一个表”。正确吗?