使用Sqlserver更新锁防止数据脏读
有时候我们需要控制某条记录在程序读取后就不再进行更新,直到事务执行完释放后才可以。这时候我们就可以将所有要操作当前记录的查询加上更新锁,以防止查询后被其它事务修改。这种操作只锁定表中某行而不会锁定整个表,体验更好。
测试sql代码如下:
在一个查询中执行如下语句
begin tran SELECT InvestState FROM InvestOrdersABC WITH (UPDLOCK) where id=10005 waitfor delay '00:00:10' update InvestOrdersABC set InvestState='2' where id=10005 commit tran
1、在另外的一个查询中执行以下语句
SELECT InvestState FROM InvestOrdersABC where id=10005
发现在第一个事务执行完以前查到的数值还是原来的数值0,直到更新完成后才会变成2,如果加上锁,代码如下:
SELECT InvestState FROM InvestOrdersABC WITH (UPDLOCK) where id=10005
发现sql语句必须等到第一个连接里的事务完成才执行完成,这是因为这个sql的连接的更新锁认为第一个事务里的更新锁可能会对数据进行修改,因此必须等事务执行完成才执行。此时更新锁变为排他锁。
2、如果执行更新操作:
begin tran update InvestOrders set InvestState='3' where id=10005 commit tran
发现无法更改,只能等到第一个查询完成后才会进行修改。其实和加锁不加锁已经没什么关系,为什么呢?因为SQL Server在执行INSERT、 UPDATE 或DELETE 命令时,会自动使用独占锁。
3、上文的事务未加隔离级别,事务的默认隔离级别为READ committed,不加锁因此在第1点里还可以进行查询。当数据库事务的隔离级别为REPEATABLE READ,SERIALIZABLE时,如果查询需要加共享锁:
SELECT InvestState FROM InvestOrdersABC WITH (HoldLOCK) where id=10005
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)