美文网首页
数据库锁

数据库锁

作者: 小幸运Q | 来源:发表于2020-09-11 21:12 被阅读0次

    https://www.cnblogs.com/liuqing576598117/p/10366233.html


    查看正在锁的事物:

    SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS
    

    查看等待锁的事物:

    SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS
    

    show processlist 查询表被锁进程


    (1)共享锁(读保护,读的时候不能写)

    T1: select * from table (执行N久)
    T2: update table set column1='hello' 
    

    过程:

    T1运行 (加共享锁)
    T2运行
    If T1 还没执行完
      T2等......
    else
      锁被释放
      T2执行
    endif
    

    T2之所以要等,是因为T2在执行update前,试图对table表加一个排他锁,而数据库规定同一资源上不能同时共存共享锁和排他锁。所以T2必须等T1。

    (2)更新锁(Update lock)(只锁更新,写锁)

    T1: select * from table(updlock) (加更新锁)
    update table set column1='hello'
    T2: select * from table(updlock)
    update table set column1='world'
    T3: select * from table
    

    T1执行select,加更新锁。
    T2运行,读的时候准备加更新锁,但发现已经有一个更新锁在那儿了,只好等T1更新完再select。
    T3无影响直接读。

    (3)排他锁(独占锁,Exclusive Locks)

    T1: update table set column1='hello' where id<1000
    T2: update table set column1='world' where id>1000
    

    假设T1先达,T2随后至,这个过程中T1会对id<1000的记录施加排他锁.但不会阻塞T2的update,因为位置相互独立。

    (4)意向锁(Intent Locks)

    T1: select * from table (xlock) where id=10 --意思是对id=10这一行强加排他锁
    T2: select * from table (tablock) --意思是要加表级锁
    

    假设T1先执行,T2后执行,T2执行时,欲加表锁,为判断是否可以加表锁,数据库系统要逐条判断table表每行记录是否已有排他锁,如果发现其中一行已经有排他锁了,就不允许再加表锁了。只是这样逐条判断效率太低了。

    实际上,数据库系统不是这样工作的。当T1的select执行时,系统对表table的id=10的这一行加了排他锁,还同时悄悄的对整个表加了意向排他锁(IX),当T2执行表锁时,只需要看到这个表已经有意向排他锁存在,就直接等待,而不需要逐条检查资源了。

    (5)计划锁(Schema Locks)

    alter table..(加schema locks,称之为Schema modification (Sch-M) locks)
    

    DDL语句都会加Sch-M锁,该锁不允许任何其它session连接该表。连都连不了这个表了,当然更不用说想对该表执行什么sql语句了。

    (6) 间隙锁

    锁范围,阻止在区间插入新的数据,防止幻读。往往针对非唯一索引。

    触发条件:范围查询并且查询未命中记录,查询条件必须命中索引、间隙锁只会出现在REPEATABLE_READ(重复读)的事务级别中。

    (7) 临键锁

    总结来说它就是记录锁和间隙锁的组合,临键锁会把查询出来的记录锁住,同时也会把该范围查询内的所有间隙空间也会锁住,再之它会把相邻的下一个区间也会锁住。

    触发条件:范围查询并命中,查询命中了索引。


    • 如果检测到死锁怎么办?

    可以强制某个事务回滚,释放掉锁。

    举例:死锁发生的场景

    事务A 事务B
    delete from T1 where id=1  
      update T2 set xxx where id=5
    update T2 set where id=5  
      delete from T1 where id=1
    commit commit

    相关文章

      网友评论

          本文标题:数据库锁

          本文链接:https://www.haomeiwen.com/subject/dcibektx.html