zoukankan      html  css  js  c++  java
  • MySQL可重复读隔离级别的实现原理

    1、原理

    MySQL默认的隔离级别是可重复读,即:事务A在读到一条数据之后,此时事务B对该数据进行了修改并提交,那么事务A再读该数据,读到的还是原来的内容。 那么MySQL可重复读是如何实现的呢?

    使用的的一种叫MVCC的控制方式 ,即Mutil-Version Concurrency Control,多版本并发控制,类似于乐观锁的一种实现方式

    实现方式:

    InnoDB在每行记录后面保存两个隐藏的列来,分别保存了这个行的创建时间和行的删除时间。这里存储的并不是实际的时间值,而是系统版本号,当数据被修改时,版本号加1
    在读取事务开始时,系统会给当前读事务一个版本号,事务会读取版本号<=当前版本号的数据
    此时如果其他写事务修改了这条数据,那么这条数据的版本号就会加1,从而比当前读事务的版本号高,读事务自然而然的就读不到更新后的数据了

    2、增删改查

    假设初始版本号为1:

    INSERT

    insert into user (id,name) values (1,'Tom');
    
    id name create_version delete_version
    1 Tom 1

    下面模拟一下文章开头的场景:

    SELECT (事务A)

    select * from user where id = 1;
    

    此时读到的版本号为1

    UPDATE(事务B)

    update user set name = 'Jerry' where id = 1;
    

    在更新操作的时候,该事务的版本号在原来的基础上加1,所以版本号为2。
    先将要更新的这条数据标记为已删除,并且删除的版本号是当前事务的版本号,然后插入一行新的记录

    id name create_version delete_version
    1 Tom 1 2
    1 Jerry 2

    SELECT (事务A)

    此时事务A再重新读数据:

    select * from user where id = 1;
    

    由于事务A一直没提交,所以此时读到的版本号还是为1,所以读到的还是Tom这条数据,也就是可重复读

    DELETE

    delete from user where id = 1;
    

    在删除操作的时候,该事务的版本号在原来的基础上加1,所以版本号为3
    删除时,将当前版本号作为删除版本号

    id name create_version delete_version
    1 Jerry 2 3
  • 相关阅读:
    js--数组中的最值
    js--数组合并并且去重
    js---数组去重的方法总结???
    input 输入框又被输入法遮挡啦
    使用装饰者模式改善既有代码
    简易的 webpack + vue 完成本地化数据 mock
    vue 数据持久化(刷新保存数据)的探索
    JavaScript await 与 promise 的纠葛
    javascript 函数的暂停和恢复
    Symbol 小妙处
  • 原文地址:https://www.cnblogs.com/lmj612/p/10598971.html
Copyright © 2011-2022 走看看