课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
锁的引用在软件编程开发项目中是非常常见的一个功能,下面我们就通过案例分析来了解一下,软件开发死锁产生原因与解决方法。
一、什么是死锁
如下:两个事务都持有对方需要的锁,并且在等待对方释放,并且双方都不会释放自己的锁。
二、为什么会形成死锁
看到这里,也许你会有这样的疑问,事务和谈判不一样,为什么事务不能使用完锁之后立马释放呢?居然还要操作完了之后一直持有锁?这就涉及到MySQL的并发控制了。
MySQL的并发控制有两种方式,一个是MVCC,一个是两阶段锁协议。那么为什么要并发控制呢?是因为多个用户同时操作MySQL的时候,为了提高并发性能并且要求如同多个用户的请求过来之后如同串行执行的一样(可串行化调度)。
两阶段锁协议(2PL)
官方定义:
两阶段锁协议是指所有事务必须分两个阶段对数据加锁和解锁,在对任何数据进行读、写操作之前,事务先要获得对该数据的封锁;在释放一个封锁之后,事务不再申请和获得任何其他封锁。
对应到MySQL上分为两个阶段:
扩展阶段(事务开始后,commit之前):获取锁
收缩阶段(commit之后):释放锁
就是说呢,只有遵循两段锁协议,才能实现可串行化调度。
但是两阶段锁协议不要求事务必须一次将所有需要使用的数据加锁,并且在加锁阶段没有顺序要求,所以这种并发控制方式会形成死锁。
三、MySQL如何处理死锁?
MySQL有两种死锁处理方式:
等待,直到超时(innodb_lock_wait_timeout=50s)。
发起死锁检测,主动回滚一条事务,让其他事务继续执行(innodb_deadlock_detect=on)。
由于性能原因,一般都是使用死锁检测来进行处理死锁。
死锁检测
死锁检测的原理是构建一个以事务为顶点、锁为边的有向图,判断有向图是否存在环,存在即有死锁。
回滚
检测到死锁之后,选择插入更新或者删除的行数少的事务回滚,基于
INFORMATION_SCHEMA.INNODB_TRX表中的trx_weight字段来判断。
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。