什么是锁?死锁的三种情况及解决办法

  • Post author:
  • Post category:其他




简介

锁是计算机协调多个进程或线程并发访问某一资源的机制(避免发生资源争抢)。



锁的分类

  1. 对数据操作的粒度分

    1. 表锁:操作时,会锁定整个表,不会出现死锁。
    2. 行锁:操作时,会锁定当前操作行,会出现死锁。
存储引擎 表锁 行锁 加锁方式
InnoDB 支持 支持 在执行UPDATE、DELETE、INSERT语句时,自动给涉及的数据加

排他锁

,一般的SELECT语句

不加任何锁
MyISAM 支持 不支持 在执行SELECT前会自动给涉及的所有表加

共享锁

,在执行UPDATE、DELETE、INSERT等操作前,给涉及的表加

排他锁
  1. 对数据操作的类型分


    1. 共享锁

      (Share Locks,读锁):事务A对数据加锁后,只能读取加锁的数据,不能读取其他数据,其他事务可以读取,均不能修改(增,删、改)。

    2. 排他锁

      (Exclusive Locks,写锁):事务A操作时,其他事务不能对数据对象读取和修改。
--表锁模式
--加表锁
lock table table_name read;--共享锁
lock table table_name write;--排他锁
--
--解锁
unlock table_name;
--行锁模式
--加行锁
select * from tab_name where...lock in share mode;--加共享锁(in share mode)
select * from tab_name where...for update;--加排他锁(for update)


提醒:共享锁可以多个事务同时对同一个数据加锁,排他锁一次性只能由一个事务对数据对象加锁



死锁的三种情况及解决办法

  1. 第一种情况:

    用户甲访问表A(锁住了A),然后访问表B;用户乙访问表B(锁住了B),然后访问表A;由于表B被用户乙锁住,用户甲必须等用户乙释放表B才能继续,同样由于表A被甲锁住,用户乙必须等用户甲释放表A才能继续,从而产生了死锁。



    解决办法:




    这种情况是由于程序的bug产生,应分析程序的逻辑,对于数据库的多表操作,应按照相同的顺序进行处理,尽量避免同时锁定两个资源。
  2. 第二种情况:

    用户甲查询一条记录,然后要修改这条记录;这时用户乙修改该条记录;此时用户甲事务里锁的性质欲由共享锁变为排他锁,而用户乙里的排他锁因为甲有共享锁存在,必须等甲释放掉共享锁,而甲因为乙的排他锁而无法变为排他锁也就不可能释放共享锁。



    解决办法:




    ①对于按钮等控件,单击后使它立即失效,不要让用户重复单击,避免同时对同一条记录进行操作。



    ②使用乐观锁、悲观锁进行控制
  3. 第三种情况:

    如果在事务中执行了一条不满足条件的update语句,则执行全表扫描,把行级锁提升为表级锁,多个这样的事务执行后,很容易产生死锁和阻塞。



    解决办法:




    SQL语句中不要使用太复杂的关联多表的查询;使用“执行计划”对SQL语句进行分析,对于有全表扫描的SQL语句,应建立相应的索引进行优化。



版权声明:本文为qq_54414607原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。