我有一个使用存储过程将数据插入SQL Server(2008)表的C#应用程序。我使用多线程来执行此操作。存储过程是从线程内部调用的。现在我的存储过程在插入数据时使用“tablock”。在执行此代码时,我收到以下错误:“事务(进程ID)与另一个进程在锁资源上死锁,并已被选为死锁牺牲品。请重新运行该事务。”
有人能帮我解决这个问题吗?
我有一个使用存储过程将数据插入SQL Server(2008)表的C#应用程序。我使用多线程来执行此操作。存储过程是从线程内部调用的。现在我的存储过程在插入数据时使用“tablock”。在执行此代码时,我收到以下错误:“事务(进程ID)与另一个进程在锁资源上死锁,并已被选为死锁牺牲品。请重新运行该事务。”
有人能帮我解决这个问题吗?
6条答案
按热度按时间qnzebej01#
当两个SQL Server进程访问相同的资源,但顺序不同时,就会发生这种情况。因此,它们最终都在等待另一个进程,这就是死锁。
有很多方法可以预防这种情况,包括:
with (nolock)
锁定提示。例如,如果Proc1先锁定table1,然后锁定table2,但Proc2先锁定table2,然后锁定table1,则会出现问题。您可以重写其中一个proc,使其以相同的顺序获取锁,以避免此问题。
vyu0f0g12#
您可以将查询封装在TRY CATCH块中,并捕获错误号(与锁相关)
然后,您可以自动重试,直到达到一定的次数。因此,您可以执行以下操作;
您还可以使用表提示,如UPDLOCK。
vpfxa7rd3#
请确定要更新或插入的字段,此字段具有非聚集索引。如果不可用,您可以先在此表上创建此字段的非聚集索引,创建后执行以下步骤。
irlmq6kh4#
我也遇到过这个问题,所以我在我的存储过程中使用了WITH(NOLOCK)after all joins,所以它工作正常,我可以修复我的问题。
dtcbnfnu5#
下面是由S Kumar Dubey提供的MSDN解决方案
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/171d9fa9-0a39-48ce-bc38-35623e0c1075/how-can-i-release-lock-on-tables?forum=transactsql
执行SP:SP_LOCK在结果中,您将获得SPID,DBID,OBJID,INDID,TYPE,RESOURCE,MODE,STATUS现在检查状态列,如果显示等待,则删除该SPID。杀死65(其中65是SPID)
似乎您需要成为SQL Server管理员才能解决此问题。
vyswwuz26#
您可以从Lock对象使用