【MySQL(十四)】事务 MVCC机制

事务的四大特性:Atomicity(原子性),Isolation(隔离性),Consistency(一致性)和Durability(持久性)。

重点说下隔离性,指的是多个事务并行执行时,效果上就像一个一个执行的。没有因为是并行而导致问题。因为系统不可能完全让事务顺序执行,这样性能太差,所以说需要在并发的同时满足隔离性。

接下来,再看下事务并发执行时会遇到怎样的问题?

脏写,或者说写覆盖。就是是A更新一行数据,还未提交,事务B又更新了同一行数据。一句话概括即使,允许事务更新未提交的事务已经更新的行。这个会导致严重的问题,比如事务B之后又回滚了,那么A的修改也会被覆盖。

脏读;

不可重复读;

幻读;

再重点看下幻读,幻读有两个特点:一是必须是别的事务插入导致的;而是必须是第二次读读到的行变多了;

隔离级别

sql标准有四种隔离级别:

当然这个也仅是标准,不同的实现会略有不同,比如mysql就可以在rr级别下避免幻读问题。另外再强调下事务与锁的关系。为了保证事务并发读,在非序列化隔离级别下,事务的普通读取都不需要加锁,非锁定读。

下面看下mysql里如何解决脏读和不可重复读问题的。

使用的是MVCC机制。

在非锁定读机制下,如何解决脏读和不可重复读问题?答案是使用快照思路,在事务读取时,先得到一份当前数据库数据的快照,只从这个快照里读数据,后面的修改都不会影响这个快照。那么真的会备份全部数据生成这个快照吗?

不会的。之前讲过数据的行格式,知道每一条数据都有rollback_pointer属性。这个是干嘛的?其实每一个事务对同一行数据的修改均会被记录到该行数据上,按照先后关系形成一个链表,而rollback_pointer指向的就是链表的头结点。这个其实是undo log,记录了修改的内容,方便后续回滚。

所以,所谓的快照,其实就是读数据的事务需要在读取前,得到读取行的一个一致性视图,这个视图就是通过undo log来得到的。也就是只读自己可以看到的修改,屏蔽不能看到的修改。

对于rc级别,每一次普通的读取语句都会计算出一个视图;而对于rr级别,因为保证需要在整个事务期间读取到相同的值,所以会在第一次普通读取语句计算出一个视图,整个事务期间就用这个视图;

那么如何得到事务的可见性视图?

在事务发起读语句时,需要记录这么几个值。

1.当前事务id为A;

2.记录当前所有活跃的事务id列表list;

3.下一个可分配的事务idC;

然后从后往前遍历回滚段链表。拿到当前undo log里的事务id,假设为D:

如果D > C,说明事务D是本事务之后开启的,不可见;

如果D < A,说明事务D在本事务开启前就已提交,可见;

否则呢,看D是否在活跃事务列表list里,如果在,事务D还未提交,不可见,否则说明已经提交,可见; 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值