【数据库】MVCC 和 乐观锁

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010900754/article/details/76888886

最近在看mysql的引擎类型,说到innodb时看到了mvcc,了解了一下。

MVCC全称是Multi-version concurrency control,多版本控制。什么意思?说白了是解决数据库读-写冲突的方法。数据库不免要支持事务,事务ACID的特性中的I,即隔离性就可以通过MVCC实现,就是说多个事务读取数据时,需要隔离,只能读到某一些值,比如已经提交的值,这就是保证事务隔离级别的方法。通过MVCC,可以在事务隔离型方面实现可重复读的级别。具体时怎么做的?每一行数据最后都会附加一些属性,存储的是最后更新这一行数据的事务的id和删除这一行数据的id(这个删除并不只是指那些delete操作,也包括了update,update实质是新插入一行,并且标记原有行为删除,这样才能让某一些事务只能读到以前的值),这个是一个全局的递增的id,由数据库来维护,这些都是不可见的。当一个update的事务提交执行以后,通常是新增一行,然后附上自己的事务id,再标记之前的那行数据的删除id。那么读事务执行时,只能读取到同时满足下面两个条件的行:

(1)更新id小于等于当前id

(2)删除id大于等于当前id

这样首先可以保证read commited隔离级别,因为只有执行到commit才会被写入数据库中,也就是前面所说的在原有行下新增一行。所以读到的数据都是已提交的。

然后,只能读取“更新id小于等于当前id”可以保证repeatable read特性。read commited只能保证读取到已提交的值,但是即使是比当前事务晚的事务做的更新,也可以读取到。比如一个读事务很长,在最后一刻才执行读,在该事务开始之后,在该事务读操作执行之前,另一个事务更新并且提交,该事务也可以读到,因为它提交了。但这就引发了重复读可能读到不同值的风险,可能这个读事务在最开始就已经读了另一个更早的更新事务更新的值,然后又发生了上述一个新的更新事务,该读事务又读了该值,这时,读取到的值就不同了。所以必须让读取事务只能读取更新域id小于等于自己的行,即可以被其他事务修改,但是该更新事务必须在当前事物之前,也就是id小于等于。这是,发生在后面的更新事务所做的操作就会被隔离。这就是MVCC实现repeatable read的原理。

那么MVCC听起来和乐观锁类似啊,都有版本号这一个概念,其实有区别。

乐观锁和MVCC处理的问题不同,乐观锁解决的是写-写冲突,只是它的机制是写入不阻塞,如果冲突就只允许一个,其他的回滚。所以我觉得乐观锁是处理事务ACID的“C”的。

展开阅读全文

没有更多推荐了,返回首页