MySQL进阶-事务隔离与锁

MySQL进阶-事务隔离与锁

Jason Lv3

note

本质上,事务隔离级别就是为了解决并发访问下的数据一致性问题的。不同的事务隔离级别,解决了不同程度的数据一致性。而我们所说的全局锁、表锁、行级锁等等,其实都是事务隔离级别的具体实现。而 MVCC、意向锁,则是一些局部的性能优化。

1.事务的隔离级别

  • 读未提交(Read Uncommitted)
    读还没有提交的数据 会产生脏读 比如 事务A读取了事务B未提交的数据 然后事务B回滚了 事务A读取的数据就无效了

  • 读已提交(Read Committed)
    读已经提交的数据 不会产生脏读 但会产生不可重复读是指事务A读取了事务B已经提交的数据 然后事务B修改了数据 事务A再次读取的数据和第一次读取的数据不一样

  • 可重复读(Repeatable Read)
    这个隔离级别解决了不可重复读的问题,只要是在同一事务范围内,那么读取到的数据就是一样的。对于 MySQL Innodb 来说,其实通过 MVCC 来实现的。但不可重复读隔离级别会产生幻读问题,即对于某个范围的数据读取,前后两次可能读取到不同的结果。

    举个例子:数据库中有 price 为 1、3、5 三个商品,此时 A 事务查询 price < 10 的商品,查询到了 3 个商品。随后 B 事务插入了一条 price 为 7 的商品。接着 A 事务继续查询 price < 10 的商品,这次却查询到了 4 个商品。可以看到「幻读」与「不可重复读」是有些类似的,只是「不可重复读」更多指的是某一条记录,而「幻读」指的则是某个范围数据。对于 MySQL Innodb 来说,其通过行级锁级别的 Gap Lock 解决了幻读的问题。

  • 串行化(Serializable)
    串行化,指的是所有事务串行执行。 这个就最简单了,不用去竞争,一个个去执行,但是效率也是最低的。

2.锁

  • 表级的意向排它锁(IX):lock mode IX。
  • 表级的插入意向锁(LOCK_INSERT_INTENTION): lock_mode X locks gap before rec insert intention
  • 行级的记录锁(LOCK_REC_NOT_GAP): lock_mode X locks rec but not gap
  • 行级的间隙锁(LOCK_GAP): lock_mode X locks gap before rec
  • 行级的 Next-key 锁(LOCK_ORNIDARY): lock_mode X
    在 Innodb 存储引擎中,我们可以通过下面的命令来查询锁的情况。
    1
    2
    3
    4
    // 开启锁的日志
    set global innodb_status_output_locks=on;
    // 查看innodb引擎的信息(包含锁的信息)
    show engine innodb status\G;
  • Title: MySQL进阶-事务隔离与锁
  • Author: Jason
  • Created at : 2023-09-08 20:11:44
  • Updated at : 2023-09-10 16:00:41
  • Link: https://xxxijason1201.github.io/2023/09/08/MySQL/事务隔离与锁/
  • License: This work is licensed under CC BY-NC-SA 4.0.
 Comments
On this page
MySQL进阶-事务隔离与锁