SQL - 如何在此UPDATE上避免并发冲突?

时间:2015-04-07 15:35:21

标签: sql sql-server sql-server-2012

我有一张桌子。多个外部流程将同时关注它&更新它。

我想编写一些SQL来更新"具有最高优先级的一行,尚未更新(由另一个外部流程)"。

进程使用下面的SQL访问我的表。但我担心的是......如果两个进程几乎同时尝试运行此代码,我不确定将会发生什么。这个代码的两个几乎同时发生的实例是否会尝试更新同一行是否存在风险?

我只是想确保编写的代码(使用CTE)在单个事务中运行SELECT和UPDATE,而不会有多个进程选择&更新同一行。如果情况不是这样,请告诉我需要更改的内容才能实现此目的。

谢谢!

WITH MostUrgentWorkAssignment AS
(
    SELECT TOP(1) *
    FROM 
        dbo.WorkAssignments a       
    WHERE
        a.UserID IS NULL
    ORDER BY 
        a.Priority
)
UPDATE MostUrgentWorkAssignment 
SET UserID = @UserID

1 个答案:

答案 0 :(得分:1)

TSQL不应该是这样的,避免不必要的CTE吗?

UPDATE [dbo].[WorkAssignments] 
    SET
           [UserId] = @UserID
    FROM
           [dbo].[WorkAssignments] [A]
        JOIN
           (
               SELECT TOP 1
                           [A].[Id]
                   FROM 
                           [dbo].[WorkAssignments] [A]       
                   WHERE
                           [A].[UserId] IS NULL
                   ORDER BY 
                           [A].[Priority]
           ) [MostUrgentWorkAssignment]
               ON [MostUrgentWorkAssignment].[Id] = [A].[Id];

如果你有一个明智的Isolation Level这个陈述是安全的。 select和update将在隐式事务中运行,因为它们是同一语句的一部分。无论是否有CTE,我都怀疑这是同样正确的。