日期:2014-05-17  浏览次数:20489 次

SQL 的独占问题
各位大神,

求救了!
在SQL上,我针对一张表一条数据进行独占,但意外的其中的另一条数据也被独占了!
但我的查询中没有写到独占那一个,
这是什么情况?

具体:
这是我独占A
BEGIN TRANSACTION
SELECT Number FROM NumberTable
 WITH(UPDLOCK,NOWAIT)
WHERE Number = 'A'
COMMIT TRANSACTION

但当我想独占B的时候,他却说我已经独占了!

BEGIN TRANSACTION
SELECT Number FROM NumberTable
 WITH(UPDLOCK,NOWAIT)
WHERE Number = 'B'

错误提示:Lock request time out period exceeded.

求大神帮帮忙,谢谢!

sql

------解决方案--------------------
你这个是因为锁等待,导致达到了设定的超时时间而报的错。没有集群的时候,单实例,一个语句如果结果集超过5000行(这个是大概的数),行锁就会升级为表锁或者页锁,所以你看看条件等于A的数据有没有查过5000。
但是比较好的方式还是找找哪里阻塞了,2005以后:
SELECT? tl.request_session_id AS WaitingSessionID ,
????????wt.blocking_session_id AS BlockingSessionID ,
????????wt.resource_description ,
????????wt.wait_type ,
????????wt.wait_duration_ms ,
????????DB_NAME(tl.resource_database_id) AS DatabaseName ,
????????tl.resource_associated_entity_id AS WaitingAssociatedEntity ,
????????tl.resource_type AS WatingResourceType ,
????????tl.request_type AS WaitingRequestType ,
????????wrt.[text] AS WaitingTSql ,
????????btl.request_type AS BlockingRequestType ,
????????brt.[text] AS BlockingTsql
FROM??? sys.dm_tran_locks tl
????????INNER JOIN sys.dm_os_waiting_tasks wt ON tl.lock_owner_address = wt.resource_address
????????INNER JOIN sys.dm_exec_requests wr ON wr.session_id = tl.request_session_id
????????CROSS APPLY sys.dm_exec_sql_text(wr.sql_handle) AS wrt
????????LEFT JOIN sys.dm_exec_requests br ON br.session_id = wt.blocking_session_id
????????OUTER APPLY sys.dm_exec_sql_text(br.sql_handle) AS brt
????????LEFT JOIN sys.dm_tran_locks AS btl ON br.session_id = btl.request_session_id

找到后,先不急着kill掉,先分析一下是什么原因。实在不行或者最终分析出来再处理,通常就是kill拉
------解决方案--------------------
lz只是在做实验吧~目的只是想证实行锁是否只锁行?
我昨天用你的语句,用聚集索引及非聚集索引做了个简单的测试,两表数据只有十几条
但是证实了我上面的说法(不严谨,但应该有这方面问题)
当用聚集索引保持u锁的时候两个会话可以分别持有两个不同的行,不会报错
当用非聚集索引的时候,同样的数据,由于NOWAIT会立即报错
具体数据页存储方面我也是一知半解,等待其他大牛解答

------解决方案--------------------
楼主,有种可能是索引行中的KeyHashValue值生成了重复值,这种的结果就是你锁定一行,相同值的其他行也会一起锁定。

对于解释KeyHashValue值可能说的要很多,你先重建下你的索引,让它们重新生成一遍KeyHashValue值即可,不妨先试试,如果重建解决你的问题,那很有可能就出在这里了