
MySQL进阶-事务隔离与锁

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