sql - 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
解决方案
对于表结构,您已经展示了 theUPDATE
和 theSELECT
都是独立的事务,并且可以使用聚集索引搜索来完成它们的工作,而无需读取不必要的行并获取不必要的锁,因此我不会特别担心此过程的死锁。
我会更担心您在同一事务中没有UPDATE
and的事实。SELECT
因此X
,一旦更新语句完成,行上的锁就会被释放,并且另一个事务可以在SELECT
执行之前更改列值(甚至删除整行)。
如果您在同一个事务中执行这两个语句,那么我仍然不会担心死锁的可能性,因为排他锁首先被占用(如果SELECT
发生在之前,那将是另一回事UPDATE
)
SELECT
您还可以通过完全删除并使用OUTPUT
子句将更新后的值返回给客户端来解决并发问题。
UPDATE Test SET Column1 = Column1 & ~2
OUTPUT INSERTED.Column1
WHERE Id = 1
推荐阅读
- java - 使用单独提交的 Java 包提交可执行文件
- c# - VB6 与 .NET 编码问题(阿拉伯语字符)
- hql - HQL 匹配字符串百分比
- asp.net - 如何从 XML 文件将数据绑定到网格视图
- r - 在 R 中编写这个嵌套 for 循环的更好方法是什么?
- git - 将函数源代码添加到源代码控制存储库时如何正确处理 local.settings.json 文件中的机密
- delphi - Delphi Firemonkey Frames - 如何获取框架使用的事件OnEnter和OnExit
- scala - 为什么火花数据帧上的“withColumn”转换不检查外部列表中的记录?
- javascript - React/Redux 在组件级别链接异步 thunk 操作
- html - 付费视频平台 vs HTML5