如何解决SQL Server错误1222,即解锁SQL Server表

80

我在一个数据库中使用数据加载器将数据加载到原始表中。但今天,由于未知原因,数据加载器卡住了。然后我从Windows任务管理器停止了数据加载器。但是当我再次尝试在原始表中加载数据时,发现它被锁定,我无法对其进行任何操作。我尝试重新启动SQL Server服务,但问题没有解决。而且我没有权限在此服务器上终止进程。

以下是SQL Server显示的消息。

执行Transact-SQL语句或批处理时发生异常。(Microsoft.SqlServer.ConnectionInfo)

程序位置:

在 Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType)
在 Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(StringCollection sqlCommands, ExecutionTypes executionType)
在 Microsoft.SqlServer.Management.Smo.ExecutionManager.ExecuteNonQuery(StringCollection queries)
在 Microsoft.SqlServer.Management.Smo.SqlSmoObject.ExecuteNonQuery(StringCollection queries, Boolean includeDbContext)
在 Microsoft.SqlServer.Management.Smo.NamedSmoObject.RenameImplWorker(String newName)
在 Microsoft.SqlServer.Management.Smo.NamedSmoObject.RenameImpl(String newName)

===================================

锁请求超时。参数@objname不明确,或者声明的@objtype (OBJECT) 错误。(.Net SqlClient 数据提供程序)


服务器名称: 162.44.25.59 错误编号: 1222
严重级别: 16 状态: 56
过程: sp_rename 行号: 282

我的SQL Server版本是2008 R2。


你试过杀死锁定表的会话ID吗?你可以在服务器上的SQL Server活动监视器中检查它,或使用sp_lock2和sp_who的组合来找到需要被终止的会话。 - askids
我没有足够的权限来执行此操作,是否有其他解决方案? - user960340
1
除了“等待”或“终止”之外,没有其他解决方案。该错误告诉您的是,另一个进程正在持有与您尝试使用的资源不兼容的锁,这与您尝试执行的操作不兼容。您可以尝试再次运行以查看阻塞显示在哪里(特别是哪个进程正在阻塞您),但最终,它需要停止正在做的事情,以便您继续进行。 - Ben Thul
5个回答

201
在SQL Server Management Studio中,要查找活动事务的详细信息,请执行以下命令。
DBCC opentran()

您将获得活动事务的详细信息,然后从活动事务的SPID中,使用以下命令获取有关SPID的详细信息。

exec sp_who2 <SPID>
exec sp_lock <SPID>

比如,如果SPID为69,则执行以下命令:

exec sp_who2 69
exec sp_lock 69

现在,您可以使用以下命令终止该进程

KILL 69

你救了我。 - GeorgeMR
3
使用kill命令会导致回滚,可能需要一些时间。您可以使用命令kill 69 with statusonly来查看更新后的进度状态。您还可以使用命令dbcc inputbuffer(69)找出是哪个SQL命令执行并导致了锁定。 - Tony
KILL {进程号} ==> 解决了我的问题。谢谢。 - Tarek El-Mallah
谢谢,伙计。你的回答非常有帮助。 - Uditsing Khati
如此简单而优雅。你今天教会了我一些东西。谢谢。 - Francesco Mantovani

22

已经有一段时间了,但上次我遇到了类似的情况:

ROLLBACK TRAN

或尝试

COMMIT

之前已经完成的工作使一切都被释放了,因此我能够清理东西并重新开始。


4
如果导致表格阻塞的查询窗口已经关闭,那么回滚/提交操作就不起作用了。只有在该查询窗口仍然打开的情况下,回滚/提交操作才有效。 - user960340
1
幸运的是,我仍然保持着窗口打开状态,不确定如果你没有这样做会发生什么。 - Paul C

4
为了避免这种情况,请确保每个"BEGIN TRANSACTION"都有对应的"COMMIT"。
以下代码虽然会提示操作成功,但是却没有提交事务:
BEGIN TRANSACTION
BEGIN TRANSACTION
<SQL_CODE?
COMMIT

关闭未提交事务的查询窗口会提示您提交事务。这通常会解决错误1222的问题。

0
我在执行查询时启用了这些 SQL 行为设置:检查 ANSI SET IMPLICIT_TRANSACTIONS。当您执行查询(例如创建、更改表或存储过程)时,您必须提交它。
只需键入 COMMIT 并执行它 F5

0
在我的情况下,我试图在一张表上禁用触发器时,遇到了错误1222“锁请求超时”。
我按照这个答案中的建议进行操作:
  1. 在SSMS中打开两个查询窗口。
  2. 在第一个窗口中,输入/粘贴由于锁定而超时的命令。在SSMS的右下角,您应该可以看到用户名和(括号内)您正在使用的连接的SPID。请注意此查询窗口连接的SPID。暂时不要执行此查询。
  3. 在第二个查询窗口中,输入/粘贴SELECT * FROM sysprocesses WHERE spid = <在步骤2中记录的SPID>
  4. 执行第一个超时的查询,在它执行的同时(但在它超时之前),切换到第二个查询窗口并执行它(即SELECT * from sysprocesses...
  5. 您应该在结果窗格中获得一些结果。查看结果中的“blocked”字段。在我的情况下,它包含了锁定表的进程的SPID。
  6. 通过执行SELECT * FROM sysprocesses WHERE spid = <步骤5中“blocked”字段中的SPID>进一步研究锁定进程。
  7. 如果可以安全终止锁定进程,请使用kill <locking SPID>终止它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接