业务场景:
对于同一张表进行操作,同时开了三条线程:
1.第一条线程,在满足条件时会对这张表进行快速更新,可能会持续一段时间
2.第二条线程,间隔2s,会对这张表的满足where条件的数据更新一次;
3.第三条线程,间隔2s,会对这张表select一次;
问题简单分析:
因为不同线程在事务中处理相同的数据时,在抢占数据库锁的过程中都拿到了这个表的锁,数据库会采取让一个执行而另一个放弃执行,会导致该错误的出现,即选作死锁牺牲品。
解决:
在update的语句中,加入 WITH (TABLOCKX),对于这个的解释:
排它锁又称为写锁((eXclusive lock,简记为X锁)),若事务T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。它防止任何其它事务获取资源上的锁,直到在事务的末尾将资源上的原始锁释放为止。在更新操作(INSERT、UPDATE 或 DELETE)过程中始终应用排它锁。
使用如:UPDATE MT_EXP_SUB WITH (TABLOCKX) SET XXX = XXX WHERE ID = X;
加上这个排他锁之后,这个死锁的问题变解决了。