在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.
这个是因为锁等待,导致达到了设定的超时时间而报的错。没有集群的时候,单实例,一个语句如果结果集超过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拉
有种可能是索引行中的KeyHashValue值生成了重复值,这种的结果就是你锁定一行,相同值的其他行也会一起锁定。
对于解释KeyHashValue值可能说的要很多,你先重建下你的索引,让它们重新生成一遍KeyHashValue值即可,不妨先试试,如果重建解决你的问题,那很有可能就出在这里了