错误:1222:已超过了锁请求超时时段

 

 

【问题原因】

刷新当前活动将调用sp_MSset_current_activity 存储过程。在定义该存储过程时,首先将lock_timeout 变量设置为5000 毫秒(ms)。然后,会创建两个全局临时表,它们针对下面的系统表在表级别发出IX 锁,在键级别发出X 锁:

tempdb..sysobjects

tempdb..sysindexes

tempdb..syscolumns

如果在5000 毫秒(ms) 内未将前面的锁授予该进程,则查询将停止,并出现症状一节中显示的错误信息。

 

再刷新一次通常会成功。但是,如果保持这两个锁的时间太长,则也会显示该错误信息。如果执行sp_lock 存储过程,则可计算出哪个进程正在对dbid 2 (tempdb) 的对象ID 1、和3 保持锁定。

 

详细见:http://support.microsoft.com/kb/308518/zh-cn

 

【解决方法】

1.查看锁信息

代码来源:http://topic.csdn.net/t/20040109/16/2650137.html

 

  create   table   #t(req_spid   int,obj_name   sysname)  

   

  declare   @s   nvarchar(4000)  

  ,@rid   int,@dbname   sysname,@id   int,@objname   sysname  

   

  declare   tb   cursor   for    

  select   distinct   req_spid,dbname=db_name(rsc_dbid),rsc_objid  

  from   master..syslockinfo   where   rsc_type   in(4,5)  

  open   tb  

  fetch   next   from   tb   into   @rid,@dbname,@id  

  while   @@fetch_status=0  

  begin  

  set   @s='select   @objname=name   from   ['+@dbname+']..sysobjects   where   id=@id'  

  exec   sp_executesql   @s,N'@objname   sysname   out,@id   int',@objname   out,@id  

  insert   into   #t   values(@rid,@objname)  

  fetch   next   from   tb   into   @rid,@dbname,@id  

  end  

  close   tb  

  deallocate   tb   

   

  select   进程id=a.req_spid  

  ,数据库=db_name(rsc_dbid)  

  ,类型=case   rsc_type   when   1   then   'NULL   资源(未使用)'  

  when   2   then   '数据库'  

  when   3   then   '文件'  

  when   4   then   '索引'  

  when   5   then   ''  

  when   6   then   ''  

  when   7   then   ''  

  when   8   then   '扩展盘区'  

  when   9   then   'RID(行 ID)'  

  when   10   then   '应用程序'  

  end  

  ,对象id=rsc_objid  

  ,对象名=b.obj_name  

  ,rsc_indid  

    from   master..syslockinfo   a   left   join   #t   b   on   a.req_spid=b.req_spid  

   

  go  

  drop   table   #t  

 

2.杀掉相应数据库的进程

代码来源:http://www.cnblogs.com/LCX/archive/2008/12/03/1346924.html

 

Create Proc Sp_KillAllProcessInDB

@DbName VarChar(100)

as

if db_id(@DbName) = Null

begin

Print 'DataBase dose not Exist'

end

else

 

Begin

Declare @spId Varchar(30)

 

DECLARE TmpCursor CURSOR FOR

Select 'Kill ' + convert(Varchar, spid) as spId

from master..SysProcesses

where db_Name(dbID) = @DbName

and spId <> @@SpId

and dbID <> 0

OPEN TmpCursor

 

FETCH NEXT FROM TmpCursor

INTO @spId

 

WHILE @@FETCH_STATUS = 0

 

BEGIN

 

Exec (@spId)

 

FETCH NEXT FROM TmpCursor

INTO @spId

 

END

 

 

CLOSE TmpCursor

DEALLOCATE TmpCursor

 

end

 

GO

--To Execute

Exec dbo.Sp_KillAllProcessInDB 'DBname'

 

然后就可以刷新数据库的表与存储过程了。

 

[]该方法也适用于数据库强制还原

 

3sp_lock的相关资料:http://msdn.microsoft.com/zh-cn/developercenters/ms187749.aspx

 

原文地址:https://www.cnblogs.com/LeimOO/p/1431829.html