参考: 微软官方api
问题日志描述
事务(进程 ID 140)与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。请重新运行该事务
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:196)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1454)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:388)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:338)
at com.microsoft.sqlserver.jdbc.TDSCommand.ex
问题排查
1、查询哪些进程导致的死锁
select request_session_id spid, object_name( resource_associated_entity_id )
tablename from sys.dm_tran_locks where resource_type = 'object'
2、查询死锁的原因
CREATE Table #Who(spid int,
ecid int,
status nvarchar(50),
loginname nvarchar(50),
hostname nvarchar(50),
blk int,
dbname nvarchar(50),
cmd nvarchar(50),
request_ID int);
CREATE Table #Lock(spid int,
dpid int,
objid int,
indld int,
[Type] nvarchar(20),
Resource nvarchar(50),
Mode nvarchar(10),
Status nvarchar(10));
INSERT INTO #Who EXEC sp_who active
--看哪个引起的阻塞,blk \
INSERT INTO #Lock EXEC sp_lock
--看锁住了那个资源id,objid
DECLARE @DBName nvarchar(20);
SET @DBName='czggzy'
SELECT #Who.* FROM #Who WHERE dbname=@DBName
SELECT #Lock.* FROM #Lock
JOIN #Who
ON #Who.spid=#Lock.spid
AND dbname=@DBName;
--最后发送到SQL Server的语句
DECLARE crsr Cursor FOR SELECT blk FROM #Who WHERE dbname = @DBName AND blk <> 0;
DECLARE @blk int;
open crsr;
FETCH NEXT FROM crsr INTO @blk;
WHILE (@@FETCH_STATUS = 0)BEGIN;
dbcc inputbuffer(@blk);
FETCH NEXT FROM crsr INTO @blk;
END;
close crsr;
DEALLOCATE crsr;
--锁定的资源
SELECT #Who.spid,
hostname,
objid,
[type],
mode,
object_name(objid) as objName FROM #Lock JOIN #Who ON #Who.spid =#Lock.spid AND dbname = @DBName WHERE objid <> 0;
DROP Table #Who;
DROP Table #Lock;
问题处理
杀死进程
kill spid --杀死进程
首先,感谢您分享了这篇关于SQL Server死锁问题排查的博客。从您的文章中,我了解到了如何通过查询进程、分析死锁原因和处理死锁的方法。对于遇到类似问题的读者来说,这是非常有帮助的。在这里,我会对您的文章提一些建议和反馈。
首先,您提到了使用Microsoft官方API文档作为参考,这是一个很好的做法,因为官方文档通常是最权威和最准确的。同时,您还提供了日志描述,让读者更加清楚地了解问题的场景。
在问题排查部分,您给出了通过SQL查询来查找导致死锁的进程和原因的方法。这些查询语句非常实用,能够帮助读者快速定位问题。但是,这部分可以再加上一些解释,以帮助读者理解每个查询语句的作用和结果。例如,您可以解释一下
sys.dm_tran_locks
和sp_who
等系统视图或存储过程的作用。在问题处理部分,您给出了杀死进程的方法。这是一个简单有效的解决方案。然而,这里可以再补充一些其他的处理方法,以供读者参考。例如,优化SQL语句、调整事务隔离级别等。
此外,您的文章结构清晰,代码格式整齐,这使得读者更容易理解和学习。但是,建议您在文章中加入一些小标题,以便读者更好地把握文章的结构。同时,可以适当添加一些空行,让文章看起来更加清爽。
总的来说,这是一篇非常实用的博客,对于解决SQL Server死锁问题有很大的帮助。希望您能继续分享更多的经验和知识,为读者提供更多的帮助。再次感谢您的分享!