前言
在Mysql里面我们知道事务的隔离级别从高到低依次是serializable(串行化)、REPETABLE—READ(可重复读)、Read Commit(读已提交)、
Read UnCommint(读未提交),并且如果不设置好事务的隔离级别的话,又回出现一系列的问题,如脏读、幻读、不可重复读的情况,从而会操成我们在业务逻辑查询的时候出现数据不一致的情况,最常见的问题就是支付、扣减、查询账户数据不一致的问题;
MVCC多版本并发机制
MVCC最主要是用来解决大部分数据库幻读的情况,在几种情况里面其实最难解决的就是数据的幻读,脏读和不可重复读的问题,通过设置RR隔离级别就可以实现;
快照读
这里有一个快照读的概念,相对另外的一个概念就是当前读,读取当前最新的数据,相当于在select 后面加了 for update 锁;
SELECT * FROM TABLE FOR UPDATE
这里的快照读,快照到底存在哪里呢,当然是存在Mysql的日志文件里面了,UndoLog当中,UndoLog是Mysql中的事务文件,会存储更新前的数据,需要回滚的时候会回滚到之前记录的快照数据;
隐式字段
数据库行记录的隐式字段,是除去我们定义可见字段的另外一些后台隐藏字段,其作用也是非常大的;
- db_row_id:如果表中没有定义主键id,那么在生成的时候自动创建row_id隐藏主键;
- db_trx_id:事务id,会记录最新一次修改的事务id
- db_roll_ptr:回滚指针,指向UndoLog中上一个快照版本
Read View
Read View主要解决我们通过快照,具体应该找到哪个当前这个事务的快照,因为UndoLog会存储很多快照,需要读取本次事务的快照;
- trx_ids:未提交事务的id列表
- low_limit_id:下一个事务的id
- up_limit_id:未提交事务的最小id
- creator_trx_id:创建Read View事务id
开启事务,这个事务ID是自增长,事务大的ID可以看到事务小的ID的变更结果;
双RR隔离级别情景
场景一:
创建table_user表,插入3条数据
2. 新增:
begin;
insert into table_user(id,age,name,create_time) VALUES(null,19,'xxx',now());
commit;
select * from table_user where age>15 and age