• MySQL一致性非锁定读


    一致性非锁定读(consistent nonlocking read)是指InnoDB存储引擎通过多版本控制(multi versionning)的方式来读取当前执行时间数据库中行的数据,如果读取的行正在执行DELETE或UPDATE操作,这是读取操作不会因此等待行上锁的释放。相反的,InnoDB会去读取行的一个快照数据

    上面展示了InnoDB存储引擎一致性的非锁定读。之所以称为非锁定读,因为不需要等待访问的行上X锁的释放

    快照数据是指该行之前版本的数据,该实现是通过undo段来完成。而undo用来事务中的回滚数据,因此快照数据本身没有额外的开销,此外,读取快照数据不需要上锁,因为没有事务需要对历史数据进行修改操作

    可以看到,非锁定读机制极大地提高了数据库的并发性,在InnoDB存储引擎的默认设置下,这是默认的读写方式,即读不会占用和等待表上的锁。但是在不同的事务隔离级别下,读取的方式不同,并不是每个事务隔离级别下都是采用非锁定的一致性读,此外,即使使用非锁定的一致性读,但是对于快照数据的定义也各不相同

    快照其实是当前行数据之前的历史版本,每行记录可能有多个版本,如图显示,一个行记录可能有不止一个快照数据,一般称这种技术为多版本技术,因此带来的并发控制。称为多版本并发控制(Multi Version Concurrency Control,MVCC)

    在事务隔离级别RC和RR下,InnoDB存储引擎引擎使用非锁定的一致性读。然而,对于快照数据的定义却不相同。在rc事务隔离级别下,对于快照数据,非一致性读总是被锁定行的最新一份快照数据.而在RR事务隔离级别下,对于快照数据,非一致性读总是读取事务开始时的行数据版本。


    测试表中数据如下:
    mysql> select * from t_test where id=20;
    +----+--------+
    | id | name |
    +----+--------+
    | 20 | test20 |
    +----+--------+
    1 rows in set (0.00 sec)

    在RC隔离级别下
    在会话1:
    mysql> select @@tx_isolation;
    +----------------+
    | @@tx_isolation |
    +----------------+
    | READ-COMMITTED |
    +----------------+
    1 row in set, 1 warning (0.00 sec)

    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)

    mysql> select * from t_test where id=20;
    +----+--------+
    | id | name |
    +----+--------+
    | 20 | test20 |
    +----+--------+
    1 row in set (0.00 sec)


    在会话2:
    mysql> select @@tx_isolation;
    +----------------+
    | @@tx_isolation |
    +----------------+
    | READ-COMMITTED |
    +----------------+
    1 row in set, 1 warning (0.00 sec)

    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)

    mysql> select * from t_test where id=20;
    +----+--------+
    | id | name |
    +----+--------+
    | 20 | test20 |
    +----+--------+
    1 row in set (0.00 sec)

    mysql> update t_test set id=200 where id=20;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1 Changed: 1 Warnings: 0

    mysql> commit;
    Query OK, 0 rows affected (0.06 sec)

    再到会话1中查询,结果为空
    mysql> select * from t_test where id=20;
    Empty set (0.01 sec)


    在RR隔离级别下
    在会话1:
    mysql> select @@tx_isolation;
    +-----------------+
    | @@tx_isolation |
    +-----------------+
    | REPEATABLE-READ |
    +-----------------+
    1 row in set, 1 warning (0.00 sec)

    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)

    mysql> select * from t_test where id=20;
    +----+--------+
    | id | name |
    +----+--------+
    | 20 | test20 |
    +----+--------+
    1 row in set (0.00 sec)


    在会话2:
    mysql> select @@tx_isolation;
    +-----------------+
    | @@tx_isolation |
    +-----------------+
    | REPEATABLE-READ |
    +-----------------+
    1 row in set, 1 warning (0.00 sec)

    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)

    mysql> select * from t_test where id=20;
    +----+--------+
    | id | name |
    +----+--------+
    | 20 | test20 |
    +----+--------+
    1 row in set (0.00 sec)

    mysql> update t_test set id=200 where id=20;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1 Changed: 1 Warnings: 0

    mysql> commit;
    Query OK, 0 rows affected (0.06 sec)

    再到会话1中查询,结果为
    mysql> select * from t_test where id=20;
    +----+--------+
    | id | name |
    +----+--------+
    | 20 | test20 |
    +----+--------+
    1 row in set (0.00 sec)

  • 相关阅读:
    解决代码冲突问题
    一些自己踩到的坑
    鼠标加特效
    在django里写一个脚本,脚本里可以使用django里的model
    在linux 上用系统命令systemctl 执行python脚本
    scp 传输命令
    使用django-cors-headers 来解决跨域问题
    访问 Django 项目的静态资源
    如何用ORM自定义排序
    Mac 安装 Novicat
  • 原文地址:https://www.cnblogs.com/liang545621/p/9441678.html
Copyright © 2020-2023  润新知