这篇文章主要介绍了mysql 数据库innodb死锁原因及解决办法,需要的朋友可以参考下:
在一些涉及到数量扣减的业务场景中为了保持数据的一致性, 通常需要把一些不同资源(行或表)的插入或修改放在一个事务中提交给数据库, 这样在多并发情况下很容易造成死锁。
这里以订单和明细举例:
比如订单和多个订单明细对应不同的货物, 不同的订单会包含相同的货物, 这个大家容易理解吧,不同的人当然可以买同样的东西了。
下单环境是多并发这个应该没有异议了, 那这个时候存在并发 + 相同资源的争夺, 产生死锁的高危环境。
当存在上图的两个线程, 这个时候就会产生(DeadLock), A和B互相锁住(X锁)了对方需要的必要资源, 死锁形成的具体机制可以参考上一篇文章。
这个时候数据库会检测到死锁同时kill其中一个线程, 通常是复杂度低资源少的线程。
如何预防避免当前场景下的死锁:
1. 提高线程的性能, 加快执行速度及时释放出资源。
2. 按顺序执行资源的修改, 简单的说按顺序执行对资源修改的sql语句。这个时候在线程A执行的时候占用了资源”库存1“, 线程B会等待锁, 但是双方并没有互相占用对方资源形成首尾互相衔接的死锁条件。因此在线程A执行完毕后,线程B会获得相应的资源完成提交,lock wait的时间默认一般是50秒, 所以要避免那种超长的批量提交。