读/写死锁
我喜欢写死锁这个话题,因为在你写代码的时候,如果不考虑仔细,会有太多不同的方法和情况造成死锁。在今天的文章里,我想向你展示下,从同个表,用不同的顺序来读写记录时,会发生死锁的情况。
读/写死锁
下列代码展示了简单的表定义,这里我也插入2条记录。
-- Create a new table CREATE TABLE Foo ( Col1 INT IDENTITY(1, 1) NOT NULL PRIMARY KEY, Col2 INT, Col3 INT ) GO -- Insert 2 records INSERT INTO Foo VALUES (1, 1), (2, 2) GO SELECT * FROM Foo GO
现在假设下列情况:你有2个查询,用来读写访问记录,但你用不同的顺序访问记录。第1个事务进行下列操作
- UPDATE第1条记录
- SELECT第2条记录
第2个事务用相反的顺序访问同样的记录:
- UPDATE第2条记录
- SELECT第1条记录
下列代码展示了这2个事务:
-- UPDATE 1st record -- SELECT 2nd record BEGIN TRANSACTION UPDATE Foo SET Col3 = 3 WHERE Col1 = 1 SELECT * FROM Foo WHERE Col1 = 2 ROLLBACK GO -- UPDATE 2nd record -- SELECT 1st record BEGIN TRANSACTION UPDATE Foo SET Col3 = 3 WHERE Col1 = 2 SELECT * FROM Foo WHERE Col1 = 1 ROLLBACK GO
如果时机合适的话,这里很容易触发死锁。因为2个事务都要在第1条和第2条记录上获得排它锁(X),然后他们不能在另一条记录上获得共享锁(S)——死锁发生!
你如何解决这个死锁呢?有很多方法:
- 在你整个事务里按同样的顺序访问记录(第1条,然后第2条)
- 在事务外进行SELECT语句
- 在SELECT语句期间,启用提交读快照隔离级别( Read Committed Snapshot Isolation )来避免共享锁
小结
在今天的文章里,我向你展示了,SQL Server里,当你在一个表,在不同的顺序访问的事务里,是很容易触发死锁的。当你写你的查询时,你必须要认真考虑,按实际情况实现你的查询。经常有其他人可以阻塞你。
原文链接:
https://www.sqlpassion.at/archive/2016/12/19/writeread-deadlocks
注:此文章为WoodyTu学习MS SQL技术,收集整理相关文档撰写,欢迎转载,请在文章页面明显位置给出此文链接!
若您觉得这篇文章还不错请点击下右下角的推荐,有了您的支持才能激发作者更大的写作热情,非常感谢!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?