处理sql server的死锁 [kill spid]

出现死锁的解决办法

  1. 在master中创建查看死锁的存储过程

    [sql] view plaincopy

    1. use master
    2. go
    3. create procedure sp_who_lock
    4. as
    5. begin
    6. declare @spid int,@bl int,
    7. @intTransactionCountOnEntry  int,
    8. @intRowcount    int,
    9. @intCountProperties   int,
    10. @intCounter    int
    11. create table #tmp_lock_who (
    12. id int identity(1,1),
    13. spid smallint,
    14. bl smallint)
    15. IF @@ERROR<>0 RETURN @@ERROR
    16. insert into #tmp_lock_who(spid,bl) select  0 ,blocked
    17. from (select * from sysprocesses where  blocked>0 ) a
    18. where not exists(select * from (select * from sysprocesses where  blocked>0 ) b
    19. where a.blocked=spid)
    20. union select spid,blocked from sysprocesses where  blocked>0
    21. IF @@ERROR<>0 RETURN @@ERROR
    22. -- 找到临时表的记录数
    23. select  @intCountProperties = Count(*),@intCounter = 1
    24. from #tmp_lock_who
    25. IF @@ERROR<>0 RETURN @@ERROR
    26. if @intCountProperties=0
    27. select ‘现在没有阻塞和死锁信息‘ as message
    28. -- 循环开始
    29. while @intCounter <= @intCountProperties
    30. begin
    31. -- 取第一条记录
    32. select  @spid = spid,@bl = bl
    33. from #tmp_lock_who where Id = @intCounter
    34. begin
    35. if @spid =0
    36. select ‘引起数据库死锁的是: ‘+ CAST(@bl AS VARCHAR(10)) + ‘进程号,其执行的SQL语法如下‘
    37. else
    38. select ‘进程号SPID:‘+ CAST(@spid AS VARCHAR(10))+ ‘被‘ + ‘进程号SPID:‘+ CAST(@bl AS VARCHAR(10)) +‘阻塞,其当前进程执行的SQL语法如下‘
    39. DBCC INPUTBUFFER (@bl )
    40. end
    41. -- 循环指针下移
    42. set @intCounter = @intCounter + 1
    43. end
    44. drop table #tmp_lock_who
    45. return 0
    46. end

在master中创建删除指定数据库的死锁的存储过程

[sql] view plaincopy

  1. use master
  2. go
  3. if exists (select * from dbo.sysobjects where id = object_id(N‘[dbo].[p_killspid]‘) and OBJECTPROPERTY(id, N‘IsProcedure‘) = 1)
  4. drop procedure [dbo].[p_killspid]
  5. GO
  6. create proc p_killspid
  7. @dbname varchar(200)    --要关闭进程的数据库名
  8. as
  9. declare @sql  nvarchar(500)
  10. declare @spid nvarchar(20)
  11. declare #tb cursor for
  12. select spid=cast(spid as varchar(20)) from master..sysprocesses where dbid=db_id(@dbname)
  13. open #tb
  14. fetch next from #tb into @spid
  15. while @@fetch_status=0
  16. begin
  17. exec(‘kill ‘[email protected])
  18. fetch next from #tb into @spid
  19. end
  20. close #tb
  21. deallocate #tb
  22. go
  1. 查看死锁

  2. [sql]
    1. exec master..sp_who_lock
  3. exec master..sp_who_lock
  4. 删除死锁

    [sql] view plaincopy

    1. exec master..p_killspid ‘dbname‘

避免死锁

  1. 按同一顺序访问对象

    如果所有并发事务按同一顺序访问对象,则发生死锁的可能性会降低。例如,如果两个并发事务获得 Supplier 表上的锁,然后获得 Part 表上的锁,则在其中一个事务完成之前,另一个事务被阻塞在 Supplier 表上。第一个事务提交或回滚后,第二个事务继续进行。不发生死锁。将存储过程用于所有的数据修改可以标准化访问对象的顺序。

  2. 避免事务中的用户交互

    避免编写包含用户交互的事务,因为运行没有用户交互的批处理的速度要远远快于用户手动响应查询的速度,例如答复应用程序请求参数的提示。例如,如果事务正在等待用户输入,而用户去吃午餐了或者甚至回家过周末了,则用户将此事务挂起使之不能完成。这样将降低系统的吞吐量,因为事务持有的任何锁只有在事务提交或回滚时才会释放。即使不出现死锁的情况,访问同一资源的其它事务也会被阻塞,等待该事务完成。

  3. 保持事务简短并在一个批处理中

    在同一数据库中并发执行多个需要长时间运行的事务时通常发生死锁。事务运行时间越长,其持有排它锁或更新锁的时间也就越长,从而堵塞了其它活动并可能导致死锁。

    保持事务在一个批处理中,可以最小化事务的网络通信往返量,减少完成事务可能的延迟并释放锁。

  4. 使用低隔离级别

    确定事务是否能在更低的隔离级别上运行。执行提交读允许事务读取另一个事务已读取(未修改)的数据,而不必等待第一个事务完成。使用较低的隔离级别(例如提交读)而不使用较高的隔离级别(例如可串行读)可以缩短持有共享锁的时间,从而降低了锁定争夺。

    [sql] view plaincopy

    1. ALTER DATABASE [dbname]
    2. SET READ_COMMITTED_SNAPSHOT ON

使用绑定连接

使用绑定连接使同一应用程序所打开的两个或多个连接可以相互合作。次级连接所获得的任何锁可以象由主连接获得的锁那样持有,反之亦然,因此不会相互阻塞。

转载:https://blog.csdn.net/YKPkaiping/article/details/38068463

原文地址:https://www.cnblogs.com/PBIN/p/10912166.html

时间: 2024-11-03 22:24:47

处理sql server的死锁 [kill spid]的相关文章

SQL server下死锁问题

这几天在做一个项目,以前都没怎么搞过多线程,现在开始,只有边学边做了. 一开始的时候,程序报错是,是提示发生死锁,刚开始,自己没什么经验,以为是程序代码的死锁,就用lock代码,把程序给锁起来了,运行程序后,发现有超时现象,查阅资料,后来断定,这个问题是死锁是发生是SQL server上的,特地找了下SQL2008的书,看了下,死锁的解释. 共享锁 排他锁 更新锁 自定义锁 然后查了资料, 查询SQL死锁的 存储过程 create procedure sp_who_lock   as   beg

sql server 查询和Kill死锁进程

查询死锁进程语句 select        request_session_id spid,       OBJECT_NAME(resource_associated_entity_id) tableName    from        sys.dm_tran_locks   where        resource_type='OBJECT' 杀死死锁进程语句 kill spid

Sql Server 检测死锁的SQL语句

首先创建一个标量值函数DigLock,用来递归检测SqlServer中的每一个会话是否存在加锁循环,如果该函数最终返回1则表示检测到了加锁循环 (也就是说检测到了死锁),如果最终返回0则表示没有检测到加锁循环. 1 CREATE FUNCTION [dbo].[DigLock] 2 ( 3 @spid int, 4 @orginSpid int 5 ) 6 RETURNS bit 7 AS 8 BEGIN 9 declare @blockedSpid int=null; 10 11 select

SQL SERVER - 谈死锁的监控分析解决思路

1 背景 1.1 报警情况 最近整理笔记,打算全部迁移到EVERNOTE.整理到锁这一部分,里边刚好有个自己记录下来的案例,重新整理分享下给大家. 某日中午,收到报警短信,DB死锁异常,单分钟死锁120个. 死锁的xml文件如下: 1 <deadlock-list> 2 <deadlock victim="process810b00cf8"> 3 <process-list> 4 <process id="process810b00c

Sql Server 2008 死锁 查询和杀死

Create procedure [dbo].[sp_who_lock] ( @bKillPID Bit=0 -- 0: 查询 1: 结束掉相对应的死锁ID (可能导致数据异常)) as begin declare @spid int declare @blk int declare @count int declare @index int declare @lock tinyint set @lock=0 create table #temp_who_lock ( id int identi

查询MS SQL Server数据库死锁的一个存储过程

查询Sqlserver数据库死锁的一个存储过程 使用sqlserver作为数据库的应用系统,都避免不了有时候会产生死锁.死锁出现以后,维护人员或者开发人员大多只会通过sp_who来查找死锁的进程,然后用sp_kill杀掉. 利用sp_who_lock这个存储过程,可以很方便的知道哪个进程出现了死锁,出现死锁的问题在哪里. --创建或修改sp_who_lock存储过程 CREATE procedure sp_who_lock --ALTER procedure sp_who_lock as beg

SQL SERVER 查询死锁

方法一: WITH    CTE_SID ( BSID, SID, sql_handle ) AS ( SELECT   blocking_session_id , session_id , sql_handle FROM     sys.dm_exec_requests WHERE    blocking_session_id <> 0 UNION ALL SELECT   A.blocking_session_id , A.session_id , A.sql_handle FROM  

SQL Server 查看死锁的存储过程(转载)

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_who_lock]') and OBJECTPROPERTY(id, N'IsProcedure') = 1) drop procedure [dbo].[sp_who_lock] GO use master go create procedure sp_who_lock as begin declare @spid int,@bl int, @int

SQL Server中解决死锁的新方法介绍

SQL Server中解决死锁的新方法介绍 数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过SQL Server 2005, 现在似乎有了一种新的解决办法. 将下面的SQL语句放在两个不同的连接里面,并且在5秒内同时执行,将会发生死锁. <ccid_nobr> <ccid_code>use Northwindbegin tran insert into Orders(CustomerId) values(@#[email protected]#)