积极答复者
在使用SELECT的时候如何加锁?

问题
-
大家好。
本人对数据库不是很熟,现在做开发遇到这样一个问题需要解决,我需要执行一个事务,语句包括:
- 用主键查询表的一条记录
- 更新该记录的状态
我的要求是,事务开始后,其他事务不能读取该条记录,但我们现在事务的隔离级别是READ COMMITTED,在执行第一条语句后,执行第二条语句之前,其他事务仍然能够访问该条记录,我的查询语句是这么写的:
SELECT * FROM Orders WITH(XLOCK) WHERE OrderID=1
系统使用的是ADO.NET,用SqlCommand发送SQL来和数据库交互的,请问该怎么解决这个问题?
谢谢大家!
答案
-
Hi 怡红公子,
我知道为什么上面的XLOCK为什么无法阻塞其他session 获取的该KEY的SLOCK了,因为其他session 读取该数据的时候根本不需要获取那个SLOCK,这是SQL SERVER锁机制的一种优化手段。
这个问题我记得以前讨论过:
- 已编辑 Jacky_shen 2012年2月21日 15:46
- 已标记为答案 Zhang Yuteng 2012年2月23日 4:17
全部回复
-
SELECT * FROM Orders WITH(XLOCK, HOLDLOCK) WHERE OrderID=1
READ COMMITTED级别下,select发出的锁在语句结束后就取消,不会保持到整个事务结束,所以要加holdlock。
但注意orderid要有索引,不然会造成block。
想不想时已是想,不如不想都不想。
- 已建议为答案 Molly Chen_Moderator 2012年2月23日 1:55
-
Yes,
session 1
begin Transaction
SELECT * FROM OrdersWITH(XLOCK, HOLDLOCK)WHERE OrderID=1
session 2
SELECT * FROM Orders WHERE OrderID=1
惊奇的发现session 2没有被blocked,立马拿出SQL Profiler跟踪LOCK的获取的情况,惊奇的发现session 2的执行既然不需要KEY S LCOK。
后来试了N次后,惊奇的发现session 2又被BLOCKED了,拿出sys.dm_tran_locks查询,发现在WAIT KEY SLOCK。 就是感觉为什么前面没有被BLOCKED,后面试着试着突然就正常了,这种事情我好像碰到很多次了。
- 已编辑 Jacky_shen 2012年2月21日 12:57
-
Hi 怡红公子,
我知道为什么上面的XLOCK为什么无法阻塞其他session 获取的该KEY的SLOCK了,因为其他session 读取该数据的时候根本不需要获取那个SLOCK,这是SQL SERVER锁机制的一种优化手段。
这个问题我记得以前讨论过:
- 已编辑 Jacky_shen 2012年2月21日 15:46
- 已标记为答案 Zhang Yuteng 2012年2月23日 4:17