mysql事务问题
当前读:
select…lock in share mode (共享读锁) select…for update update , delete , insert
当前读由行锁+间隙锁实现
快照读:
由mvcc+undolog实现
MVCC机制和间隙锁的存在,解决了快照读的可重复读问题并且部分解决了快照读的幻读问题。依然存在个别情况下快照读幻读问题及当前读的幻读问题。
MVCC仅仅解决来于select的幻读,在update/delete/insert命令中的where条件查询,并没有用到MVCC,而是通过锁来解决部分情况的幻读。
比如一个事务中的两次select找出的数据是一样的,但在其他事务插入数据时,数据不会显示出来,但还是插入进去了,但是当这个事务是两次select中间夹杂着update之类的,两次查询出来的可能会带出其他事务插入的数据。
InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的,这两个列,一个保存了行的创建时间,一个保存了行的过期时间(或删除时间)。当然存储的并不是实际的时间值,而是系统版本号。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来查询到的每行记录版本号进行比较。
update
InnoDB为插入一行新纪录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识。
什么是MVCC?
多版本并发控制(Multi-Version Concurrency Control, MVCC)
仅在读提交和可重复读两种隔离级别下生效
每行记录字段都保存有 一个最近变更事务Id 一个最新删除的事务Id
事务读数据的原则就是: 读版本号小于等于当前版本的数据(意思就是读不到在当前事务之后修改的数据 避免了不可重复读)
读删除事务版本号大于等于当前版本的数据(意思就是如果这条数据在之后的事务里删了,当前事务也不能再读了)