事务有四个特征:原子性,隔离性,一致性,持久性,当多个事务并发执行的时候,隔离性就显得尤为重要
不同的隔离级别对事物的处理不同,分为四种,分别是 未授权读取(读未提交),授权读取(读已提交),可重复读取,串行化 ,其中读已提交和可重复读是最常用的
另外 : 在MySQL中事务默认自动提交,可以关闭,roll back 回滚 ,可以设置save point 回滚点,让roll back 回滚到这个时间点
MVCC 的英文全称是 Multiversion Concurrency Control ,中文意思是多版本并发控制技术。原理是,通过数据行的多个版本管理来实现数据库的并发控制,简单来说就是保存数据的历史 版本。可以通过比较版本号决定数据是否显示出来。读取数据的时候不需要加锁可以保证事务的隔离效果。乐观锁的机制
读已提交 (READ COMMITED)
每一个事务都有一个对应的事务 id ,存储在一张专门的表中,最新的版本的指针 不停地指向之前地版本,就是版本链
有两个事务 A 和 B,
第一种情况,事务已经对字段数据进行了修改
事务A,事务id为 80,将某一字段的值修改为1, (根据文字描述为主,图中的数据并不完全对应)
而事务B,事务id为 200,将同一字段的值修改为 2
当事务B查询这一字段的时候,在表中查询相应的事务 id = 200,第一个就是 200,正好对应,所以直接就能查出 值为2
而事务A要查这一字段的时候,在中要查询事务id = 80 ,第一条的事务id 200,不对应,应该根据指针 找到前一条数据 事务id 是 82 ,也不对应,接着根据指针往找,直到找到事务id是80的数据 然后取出 这一字段的值
第二种情况 事务A的事务id 为100 ,并没有字段数据进行修改,所以版本链中没有事务id为100的数据,就要读取最后提交的事务的数据,也就是版本链的链尾
这是就要引出另一个概念 ReadView ,ReadView 会保存 有哪些事务是活跃的,也就是当前还没有提交的是哪些事务,下图就是存储 81 ,82 ,200 , 300 是活跃的事务,当事务100来查询数据的时候,结合ReadView 的m_ids数组和版本链,来寻找不活跃的事务
可重复读 (REPEATABLE READ)
类似于读已提交,也会生成一个ReadView ,但是唯一的区别就是当其他的事务已经提交,也就是成为不活跃事务的时候,并不会把这个事务Id从 其中去除,这样在这个事务中读取的数据基本的任何时候都是一样,在自己没有修改的情况下,也就是重复读的数据是一样的,也即是可重复读。