您的位置:首页 > 其它

SSMS报1222错误

2016-04-04 09:44 239 查看
1. 问题

前几天在其中一个QQ群里,群友在SSMS尝试打开表或存储过程对象列表浏览时,遇一个1222的错误,根本无法浏览系统对象。




Figure-1: SSMS报1222错

乍一看,我首先反应是可能是连接远程的SQL Server;如果本地的也出现这种错误,估计是系统对象被锁。后来经过测试,果然把这个错误重视出来。

2. 重现与分析问题

创建一个存储过程,存储过程里面使用了显式事务,但不提交事务,创建时没有报错。但执行时会报错。如果这里这个存储过程被删除了,就会出现这个报错。




Figure-2: 创建测试的存储过程

执行存储过程,报了一个错误。提示BEGIN和COMMIT数目不配置。



Figure-3: 执行存储

最后删除存储过程,没有报错。




Figure-4: 删除存储过程

这时,刷新下SSMS的Object Exploer指定的数据库,然后去打开表或存储过程的列表,就会报1222错误。查询相关的锁,发现测试的存储过程使用的表被和相关页面被锁。
USE AdventureWorks2008R2
GO
SELECT
lo.request_session_id AS [session_id]
,DB_NAME(lo.resource_database_id) AS [database_name]
,lo.resource_type
,lo.resource_subtype AS [subtype]
,lo.resource_description AS [description]
,lo.request_mode as [mode]
,lo.request_owner_type as [owner_type]
,lo.request_status as [status]
,CASE WHEN lo.resource_type = 'OBJECT' THEN OBJECT_NAME(lo.resource_associated_entity_id)
WHEN lo.resource_associated_entity_id IS NULL OR lo.resource_associated_entity_id = 0 THEN NULL
ELSE OBJECT_NAME(p.[object_id])
END AS associated_entity
,wt.blocking_session_id
,wt.resource_description
FROM sys.dm_tran_locks AS lo
LEFT JOIN sys.partitions AS p
ON lo.resource_associated_entity_id = p.partition_id
LEFT JOIN sys.dm_os_waiting_tasks AS wt
ON lo.lock_owner_address = wt.resource_address
WHERE
lo.request_session_id > 50
AND lo.resource_database_id = DB_ID()
AND lo.request_session_id <> @@SPID
ORDER BY session_id ASC,resource_type ASC;
GO
Code-1: 查询锁




Figure-5: 查询结果

3. 解决与结论
找到执行存储过程的session id,然后Kill掉就行了。所以,使用显式事务时,一定要小心事务要提交或回滚,尤其是使用了多个BEGIN TRAN时。问题是解决了,还是忍不住上网再找下有没有人遇到过类型的问题。果然,人家很久之前就讨论过了。请参考:
http://www.sqlservercentral.com/Forums/Topic310216-5-1.aspx
https://support.microsoft.com/en-us/kb/308518
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  故障 排除