问题分析
- 排除是否事务导致表锁死的问题
- 调查表数据表是否过大(一般以百万为单位,过千万肯定需要缩减,未到百万问题不大)
- 是否存在同时间边修改边读的问题
- 是否存在同时间多个sql同时修改一条记录的情况
- 修改语句where条件中是否是主键
为什么需要排查这些问题
事务导致表锁死
这个问题很简单,自己写的代码把自己锁上了,那能怎么办,快删库跑路吧
数据量大
单个表数据量过大会导致增删改查都会变慢,高并发大数据时会导致大堵车,肯定会出问题。考虑分库分表添加索引加快检索速度解决一下
是否存在边写边读的问题
新手会很好奇,这俩操作有什么关系呢?
其实在查询时,sqlserver自动创建了共享锁(s锁),共享锁与共享锁之间并不冲突。但修改时需要创建独占锁,独占锁与共享锁之间是冲突的。所以会出现问题。在查询时表后面加nolock解决
多个sql同时修改一条记录
更新锁是一种中继锁。当同一项资源从原来的查询操作转换为更新操作时,锁定机制会从共享锁变为更新锁,再进一步变成独占锁。
而独占锁与独占锁之间会冲突,所以会出现问题
修改语句where条件中是否是主键
在修改语句执行中会出现锁,如果where条件是主键那么只会出现行锁,如果不是主键那就是页锁(甚至会直接锁表)。
参考资料
SQLSERVER的锁机制:点击查看
如何捕获死锁信息:点击查看
sqlserver update 锁:点击查看
辅助sql
-查询锁表session
select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName
from sys.dm_tran_locks where resource_type='OBJECT';
--杀死锁表进程
declare @spid int
Set @spid = 78 --锁表进程
declare @sql varchar(1000)
set @sql='kill '+cast(@spid as varchar)
exec(@sql);
--查看死锁列表
SELECT XEvent.query('(event/data/value/deadlock)[1]') AS DeadlockGraph
FROM (
SELECT XEvent.query('.') AS XEvent
FROM (
SELECT CAST(target_data AS XML) AS TargetData
FROM sys.dm_xe_session_targets st
INNER JOIN sys.dm_xe_sessions s
ON s.address = st.event_session_address
WHERE s.NAME = 'system_health'
AND st.target_name = 'ring_buffer'
) AS Data
CROSS APPLY TargetData.nodes('RingBufferTarget/event[@name="xml_deadlock_report"]') AS XEventData(XEvent)
) AS source;