MySQL中InnoDB的事务隔离级别和锁
1.事务隔离级别
使用 show variables like 'tx_isolation' 可查看数据库当前的隔离级别。
具体分析请查看此文:事务隔离级别
1.1 读未提交 Read uncommitted
一个事务可以读取另一个未提交事务的数据
1.2 读提交 Read committed
一个事务要等另一个事务提交后才能读取数据。
1.3 可重复读 Repeatable read
保证了在当前事务中,多次读取统一条件的数据结果保持一致。原理是快照读和GAP锁。
1.4 序列化 Serializable
串行化执行。
2. 脏读、不可重复读、幻读
2.1 脏读
在当前事务中,读取到了别的事务未提交的数据。
2.2 不可重复读
在当前事务中,多次读取同一条件的数据不一致,重点在于数据记录字段被修改了。
2.3 幻读
在当前事务中,多次读取同一条件的数据记录条数不一致,重点在删除和添加。
3. 事务隔离级别和脏读、不可重复读、幻读的关系
image.png4. 加锁分析
4.1 几个概念
-
MySQL InnoDB存储引擎,实现的是基于多版本的并发控制协议——MVCC (Multi-Version Concurrency Control)
-
在MVCC并发控制中,读操作可以分成两类:快照读 (snapshot read)与当前读 (current read)。
快照读:简单的select操作,属于快照读,不加锁。
当前读:特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。
select * from table where ? lock in share mode;
select * from table where ? for update;
insert into table values (…);
update table set ? where ?;
delete from table where ?;
所有以上的语句,都属于当前读,读取记录的最新版本。并且,读取之后,还需要保证其他并发事务不能修改当前记录,对读取记录加锁。其中,除了第一条语句,对读取记录加S锁 (共享锁)外,其他的操作,都加的是X锁 (排它锁)。 -
聚簇索引
InnoDB存储引擎的数据组织方式,是聚簇索引表:完整的记录,存储在主键索引中,通过主键索引,就可以获取记录所有的列。
4.2 demo分析
具体请查看大神的博客分析: MySQL 加锁处理分析