MySQL

Posted by 杨一 on 2020-06-16

MySQL 事务

隔离级别 脏读 不可重复读 幻读
READ_UNCOMMITTED Yes Yes Yes
READ_COMMITTED(RC) No Yes Yes
REPEATABLE_READ (RR) No No Yes
ISOLATION_SERIALIZABLE No No No

脏读:当前事务(A)中可以读到其他事务(B)未提交的数据(脏数据),这种现象是脏读。

不可重复读:在事务A中先后两次读取同一个数据,两次读取的结果不一样,这种现象称为不可重复读。
脏读与不可重复读的区别在于:前者读到的是其他事务未提交的数据,后者读到的是其他事务已提交的数据。

幻读:在事务A中按照某个条件先后两次查询数据库,两次查询结果的条数不同,这种现象称为幻读。
不可重复读与幻读的区别可以通俗的理解为:前者是数据变了,后者是数据的行数变了。

行锁

  • record lock 是专门对索引项加锁
  • gap lock 是对索引项之间的间隙加锁
  • next-key lock 则是前面两种的组合,对索引项以其之间的间隙加锁

MVCC

InnoDB 中的 RC 和 RR 隔离事务是基于多版本并发控制(MVVC)实现高性能事务。一旦数据被加上排他锁,其他事务将无法加入共享锁,且处于阻塞等待状态,如果一张表有大量的请求,这样的性能将是无法支持的。

读已提交 解决 脏读、不可重复读、幻读 等问题,使用的是MVCC:MVCC全称Multi-Version Concurrency Control,即多版本的并发控制协议。下面的例子很好的体现了MVCC的特点:在同一时刻,不同的事务读取到的数据可能是不同的(即多版本)——在T5时刻,事务A和事务C可以读取到不同版本的数据。参考链接

MVCC最大的优点是读不加锁,因此读写不冲突,并发性能好。InnoDB实现MVCC,多个版本的数据可以共存,主要是依靠数据的隐藏列(也可以称之为标记位)和undo log。其中数据的隐藏列包括了该行数据的版本号、删除时间、指向undo log的指针等等;当读取数据时,MySQL可以通过隐藏列判断是否需要回滚并找到回滚需要的undo log,从而实现MVCC。

  • binlog + redo log 两阶段提交保证持久性
  • 事务的回滚机制 保证原子性 要么全部提交成功 要么回滚
  • undo log + MVCC 保证一致性 事务开始和结束的过程不会其它事务看到 为了并发可以适当破坏一致性