大家好,我是一安~
简介
死锁指两个或多个事务相互等待对方释放锁,从而导致进程无法继续执行的一种情况。当一个事务需要锁定一些资源时,如果这些资源已经被其他事务锁定,则该事务必须等待其他事务释放锁,才能继续执行。如果多个事务同时等待对方释放锁,就会发生死锁。
总结:
互斥条件:一个资源每次只能被一个进程使用。 请求和保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 不剥夺条件:进程已获得的资源,在未使用完之前,不能被其他进程强行剥夺,只能由该进程自己释放。 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。 产生死锁的必要满足以上4个条件,缺一不可。
案例分析
表锁
用户A访问表A(锁住了表A),然后又访问表B;另一个用户B访问表B(锁住了表B),然后企图访问表A;这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B才能继续,同样用户B要等用户A释放表A才能继续,死锁就这样产生了。
行锁
如果在事务中执行了一条没有索引条件的查询,引发全表扫描,把行级锁上升为全表记录锁定(等价于表级锁),多个这样的事务执行后,就很容易产生死锁和阻塞。
如何解决
以上死锁基本是由于程序的BUG产生的,在对数据库的多表或单表操作时,尽量按照相同的顺序进行处理且避免同时锁定两个资源。
必须同时锁定两个资源时,要保证在任何时刻都应该按照相同的顺序来锁定资源。
select for update:
如果有唯一索引,命中了唯一记录:行锁,互斥锁; 如果有唯一索引,没命中: gap锁,另一个事务也可以获得这个gap锁,但是不能插入数据;(后续有死锁可能)如果有普通索引,命中了记录:行锁+ gap锁;(后续有死锁可能)如果有普通索引,没有命中记录: gap锁,和情况2相同;(后续有死锁可能)如果没有索引,直接锁全表,互斥,直接阻塞别的事务
演示
说明:
共享锁(S):允许多个事务同时读取同一份数据,但不允许对数据进行修改。当一个事务获得共享锁时,其他事务只能获得共享锁,不能获得排他锁。排他锁(X):只允许一个事务对数据进行修改,其他事务不能读取或修改该数据。当一个事务获得排他锁时,其他事务不能获得任何类型的锁。意向共享锁(IS):表示事务想要在某个数据上获得共享锁,但并不是真正的共享锁,只是一个辅助锁。当一个事务获得意向共享锁时,其他事务可以获得共享锁或意向共享锁,但不能获得排他锁。意向排他锁(IX):表示事务想要在某个数据上获得排他锁,但并不是真正的排他锁,只是一个辅助锁。当一个事务获得意向排他锁时,其他事务只能获得意向共享锁,不能获得任何类型的锁。
show VARIABLES like 'innodb_deadlock_detect' -- 查看当前死锁检测是否开启
set global innodb_deadlock_detect = OFF; --设置死锁检测关闭
set global innodb_deadlock_detect = ON; --设置死锁检测开启
-
保证资源的加锁顺序,避免循环等待的产生。 -
减少对资源的占用时间和占用范围,避免长事务,锁粒度变大的情况,可以大大减少死锁产生的概率。 -
使用乐观锁 mvcc机制,读取数据不上锁,在读情况下共享资源。
如果这篇文章对你有所帮助,或者有所启发的话,帮忙 分享、收藏、点赞、在看,你的支持就是我坚持下去的最大动力!

基于Shrio的分布式微服务权限控制和会话管理的详细设计与实现

本篇文章来源于微信公众号: 一安未来
微信扫描下方的二维码阅读本文

Comments NOTHING