首页 > 解决方案 > SQL Server 中单行中单列的更新/选择是否原子且安全?

问题描述

我想使用以下语句来更新单行的列:

UPDATE Test SET Column1 = Column1 & ~2 WHERE Id = 1

以上似乎工作。这在 SQL Server 中安全吗?我记得在非 SQL Server DBMS 中使用类似语句时可能会出现死锁(我认为它与 PostgreSQL 有关)。

表和相应存储过程的示例:

CREATE TABLE Test (Id int IDENTITY(1,1) NOT NULL, Column1 int NOT NULL, CONSTRAINT PK_Test PRIMARY KEY (Id ASC))
GO
INSERT INTO Test (Column1) Values(255) 
GO
-- this will always affect a single row only
UPDATE Test SET Column1 = Column1 & ~2 WHERE Id = 1

标签: sqlsql-servertsql

解决方案


对于表结构,您已经展示了 theUPDATE和 theSELECT都是独立的事务,并且可以使用聚集索引搜索来完成它们的工作,而无需读取不必要的行并获取不必要的锁,因此我不会特别担心此过程的死锁。

我会更担心您在同一事务中没有UPDATEand的事实。SELECT因此X,一旦更新语句完成,行上的锁就会被释放,并且另一个事务可以在SELECT执行之前更改列值(甚至删除整行)。

如果您在同一个事务中执行这两个语句,那么我仍然不会担心死锁的可能性,因为排他锁首先被占用(如果SELECT发生在之前,那将是另一回事UPDATE

SELECT您还可以通过完全删除并使用OUTPUT子句将更新后的值返回给客户端来解决并发问题。

UPDATE Test SET Column1 = Column1 & ~2 
OUTPUT INSERTED.Column1
WHERE Id = 1

推荐阅读