首先要明白快照读和当前读:
快照读: 正常的不加锁的select语句,如 select * from …
当前读: 会加锁的语句,如update, delete, insert, select * from … for update … 这种
表字段后面会有3个隐藏字段,其中row_id只要设置了主键就不会有。
另外两个id分别是事务id,trx_id 和 roll_pointer 用于记录上一条undolog的位置。
每次执行快照读的时候,会生成一个readView对象,包含4个变量
如果被访问版本的trx_id等于create_id的时候,说明该条语句和readView在同一个事务中,可以直接访问
如果被访问版本的trx_id小于 min_id 的时候,说明查询的数据已经提交,所以能够查询。
如果被访问版本的trx_id大于 max_id 的时候,说明查询的数据还未提交,所以不能查询,根据版本链去查看上一条数据。
如果被访问版本的trx_id>min_id, <max_id的时候,查看ids中是否存在,存在则查看上一次。
在RR模式下,会在第一次执行快照读的时候创建readView。
在RC模式下,每次执行快照读都会重新创建readView。
MVCC能部分解决幻读的问题,正常查询的时候,另一条事务插入一条数据,对于再次查询,并不可见。所以能解决
但是当另一个事务insert commit后,我们进行了一次当前读,就会重新生成readView,这样就解决不了幻读。
ps:是能解决重复读的,因为当前读都是会上锁的,得等commit之后才会释放,所以如果另一个事务也来修改同一条数据的话,会等另一条数据commit之后当前事务才执行,或者当前事务commit之后另一个事务才会执行