问题描述:
数据库PUBS中的authors表,想锁定CITY为aaa的记录,为什么执行下面的命令后,CITY为bbb的记录也被锁定了,无法进行UPDATE.
BEGIN TRANSACTION
SELECT * FROM authors
WITH (HOLDLOCK)
WHERE city='aaa'
如何才能锁定CITY为AAA的记录,而且CITY为BBB的记录依然能SELECT和UPDATE?
问题分析: 应该不是被锁住,应该只是检索数据的时候,需要从aaa的记录扫描到bbb的记录,而aaa被锁住了,所以扫描无法往下进行,这样看起来似乎就是bbb也被锁住了。 当然,也有可能确实是被锁住了,SQL Server的锁定默认是行级的,如果你的资源不足,则可能导致锁自动升级为页级甚至表级锁,这样会导致更多的记录被锁定。 使用下面的语句, 如果能读出数据, 则多半是第1种情况. SELECT * FROM authors WITH (READPAST) WHERE city='bbb' 如果读不出数据, 则一般是第2种情况.
问题解决方法: 让SELECT 和UPDATE 走不同的索引,这样在UPDATE 的时候,不用扫描已经锁定的数据就可以定义到记录,UPDATE 也就不会被阻塞了 指定索引用类似下面的语句: SELECT * FROM authors WITH (HOLDLOCK, INDEX=索引名) WHERE city='aaa' UPDATE A SET xx = xx FROM authors A WITH (INDEX=索引名) WHERE city='bbb' 当然,要保证仅扫描索引就可以定义到记录,否则可能还是会被阻塞。
补充 对于熟悉SQL Server锁的读者,可以通过 sp_lock,或者查询系统表 master.dbo.syslocks、master.dbo.syslockinfo来确定行为。
Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=1232660
本文针对SQL Server中出现的锁定问题进行了详细的分析与解答。当尝试锁定特定条件的记录时,发现其他不相关的记录也被锁定,文章探讨了可能的原因,并提供了解决方案,包括通过指定索引来避免不必要的锁定。
1811

被折叠的 条评论
为什么被折叠?



