MySQL中InnoDB锁的介绍及用途

巧了我就是萌 提交于 2020-03-01 03:45:53

前言

读这篇文章之前可以先了解一下MySQL中InnoDB数据结构

一、InnoDB引擎对隔离级别的支持

事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted) 可能 可能 可能
不可重复读(read-committed) 不可能 可能 可能
可重复读(repeatable-read) 不可能 不可能 InnoDB不可能
串行化(serializable) 不可能 不可能 不可能

隔离级别到底如何实现?

二、锁的介绍

1、表锁、行锁

  • 通过锁来管理不同事务对共享资源的并发访问
  • 表锁与行锁的区别:
    锁定粒度:表锁 > 行锁
    加锁效率:表锁 > 行锁
    冲突概率:表锁 > 行锁
    并发性能:表锁 < 行锁
  • InnoDB存储引擎只支持行锁,表锁是通过锁住所有行实现

2、InnoDB锁类型

  • 共享锁(行锁,又称S锁):Shared Locks
    又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁, 都能访问到数据,但是只能读不能修改。
select * from teachers WHERE id=1 LOCK IN SHARE MODE; commit/rollback
  • 排它锁(行锁,又称X锁):Exclusive Locks
    又称为写锁,简称X锁,排他锁不能与其他锁并存,如一个事务获取了一个数据行的排他 锁,其他事务就不能再获取该行的锁(共享锁、排他锁),只有该获取了排他锁的事务是可以对 数据行进行读取和修改,(其他事务要读取数据可来自于快照)
delete / update / insert 默认加上X锁 SELECT * FROM table_name WHERE ... FOR UPDATE commit/rollback
  • 意向锁共享锁(表锁):Intention Shared Locks
    表示事务准备给数据行加入共享锁,即一个数据行加共享锁前必须先取得该表的IS锁, 意向共享锁之间是可以相互兼容的
  • 意向锁排它锁(表锁):Intention Exclusive Locks
    表示事务准备给数据行加入排他锁,即一个数据行加排他锁前必须先取得该表的IX锁, 意向排它锁之间是可以相互兼容的

意向锁(IS、IX)是InnoDB数据操作之前自动加的,不需要用户干预,当事务想去进行锁表时,可以先判断意向锁是否存在,存在时则可快速返回该表不能 启用表锁

  • 自增锁:AUTO-INC Locks
    针对自增列自增长的一个特殊的表级别锁
  • 记录锁 Record Locks (行算法锁)
    锁住具体的索引项 当sql执行按照唯一性(Primary key、Unique key)索引进行数据的检索时,查询条件等值匹 配且查询的数据是存在,这时SQL语句加上的锁即为记录锁Record locks,锁住具体的索引项
    Record Locks
  • 间隙锁 Gap Locks(行算法锁)
    锁住数据不存在的区间(左开右开) 当sql执行按照索引进行数据的检索时,查询条件的数据不存在,这时SQL语句加上的锁即为 Gap locks,锁住索引不存在的区间(左开右开)
    Gap Locks
  • 临键锁 Next-key locks (行算法锁)
    锁住记录+区间(左开右闭) 当sql执行按照索引进行数据的检索时,查询条件为范围查找(between and、<、>等)并有数 据命中则此时SQL语句加上的锁为Next-key locks,锁住索引的记录+区间(左开右闭)
    Record Locks

InnoDB行锁到底锁了什么

  • InnoDB的行锁是通过给索引上的索引项加锁来实现的。
  • 只有通过索引条件进行数据检索,InnoDB才使用行级锁,否则,InnoDB 将使用表锁(锁住索引的所有记录)
  • 表锁:lock tables xx read/write;

三、利用锁解决事务并发问题

1、脏读问题
同一条数据被事务A查询,又被事务B修改数据,那么防止事务A读到事务B未提交的脏数据,我们就给事务B修改的数据加上排它锁(X锁):Exclusive Locks进行的锁定,防止事务A出现脏读。脏读
2、不可重复读问题
同一条数据需要被事务A多次查询,其中又被事务B修改数据,那么防止事务A在第二次读取数据不一致,我们就给事务A读取的数据加共享锁(S锁):Shared Locks进行的锁定,防止事务A出现不可重复读。不可重复读
3、幻读问题
当事务A需要多次查询一个范围数据时,其范围中又被事务B新增或者删除数据,防止事务A在第二次读取范围数据不一致,我们就给事务A读取的范围数据加上临键锁 Next-key,防止事务A出现幻读。幻读

四、死锁介绍和死锁避免

1、死锁介绍

  • 多个并发事务(2个或者以上);
  • 每个事务都持有锁(或者是已经在等待锁);
  • 每个事务都需要再继续持有锁;
  • 事务之间产生加锁的循环等待,形成死锁。

2、死锁的避免

  • 类似的业务逻辑以固定的顺序访问表和行。
  • 大事务拆小。大事务更倾向于死锁,如果业务允许,将大事务拆小。
  • 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概 率。
  • 降低隔离级别,如果业务允许,将隔离级别调低也是较好的选择
  • 为表添加合理的索引。可以看到如果不走索引将会为表的每一行记录添 加上锁(或者说是表锁)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!