什么是死锁?
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
产生死锁的情况
案例一:
一个用户A 访问表A(锁住了表A),然后又访问表B
另一个用户B 访问表B(锁住了表B),然后企图访问表A
这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B,才能继续
同样用户B要等用户A释放表A才能继续这就死锁了
案例二:
用户A读一条纪录,然后修改该条纪录
这时用户B修改该条纪录
这里用户A的事务里锁的性质由共享锁企图上升到独占锁(for update),而用户B里的独占锁由于A有共享锁存在所以必须等A释放掉共享锁,而A由于B的独占锁而无法上升的独占锁也就不可能释放共享锁,于是出现了死锁。
SQL Profiler
SQL Profiler是一个图形界面和一组系统存储过程,其作用如下:
- 图形化监视SQL Server查询;
- 在后台收集查询信息;
- 分析性能;
- 诊断像死锁之类的问题;
- 调试T-SQL语句;
- 模拟重放SQL Server活动;
也可以使用SQL Profiler捕捉在SQL Server实例上执行的活动。这样的活动被称为Profiler跟踪。
以死锁跟踪为例,打开死锁跟踪:
- 打开工具》登录验证
- 进入跟踪属性设置
- 常规页签设置跟踪名称
- 使用模板选择TSQL-Locks
- 事件选择
保留Deadlock graph、Lock:Deaklock、Lock:Deadlock Chain
如需分析执行时间最长的sql,保留
BatchCompleted
Stored Procedures-RPC:completed - 点击运行开始跟踪死锁SQL
跟踪完成后要及时关闭,否则会导致满内存
死锁跟踪分析:
- 点击EventClass=Deadlock graph记录,可以看到死锁发生在哪个SQL,是什么类型的锁导致死锁
- 左下方显示蓝色×表示为发生死锁的SQL
- 右边SQL是delete语句,锁的类型是PK_说明是行锁,基本可以判定原因是查询语句关联delete影响的表没有使用主键关联,进而导致死锁的;
- 根据SQL去查个案代码或标准代码,找出代码逻辑做进一步分析