美文网首页
mysql repeatable read隔离级别探索

mysql repeatable read隔离级别探索

作者: judeshawn | 来源:发表于2020-04-24 14:38 被阅读0次
    可重复读隔离级别特性:

    1.当前事务能看到的数据版本是事务内第一次执行查询或修改开始时的静态版本。无法看到其他事务对数据的修改(无论提交与否),从而避免了事务内多次读的数据版本不一样的情况。只有当前事务对数据的修改才对自己可见。

    2.对于当前事务修改过的表(insert、update或delete),在当前事务提交前,其他事务对这些表进行update、delete或破坏限制的insert时需要等待当前事务提交,当前事务提交后,其他事务的update和delete会继续执行,而破坏限制的insert会失败。

    为什么可重复读需要给表级别加update和delete锁?

    repeatable read隔离级别下 在当前会话开启一个事务,然后对T1表执行一次查询,相当于创建了一个数据的静态版本

    Current session:
    
    mysql> set session transaction isolation level repeatable read;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> select * from t1;
    +----+------+
    | id | name |
    +----+------+
    |  1 | AAA  |
    |  2 | BBB  |
    |  3 | CCC  |
    |  4 | DDD  |
    |  5 | FFF  |
    +----+------+
    5 rows in set (0.00 sec)
    
    mysql> start transaction;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> select * from t1;
    +----+------+
    | id | name |
    +----+------+
    |  1 | AAA  |
    |  2 | BBB  |
    |  3 | CCC  |
    |  4 | DDD  |
    |  5 | FFF  |
    +----+------+
    5 rows in set (0.00 sec)
    
    

    然后在另一个会话对T1表的内容进行修改并提交(自动提交,不必显式开启事务)

    Other session:
    
    mysql> update t1 set name='AAAA' where id=1;
    Query OK, 1 row affected (0.01 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    mysql> select * from t1;
    +----+------+
    | id | name |
    +----+------+
    |  1 | AAAA |
    |  2 | BBB  |
    |  3 | CCC  |
    |  4 | DDD  |
    |  5 | FFF  |
    +----+------+
    5 rows in set (0.00 sec)
    
    

    再回到当前会话,查看T1表内容,数据并没有发生变化

    Current session:
    
    mysql> select * from t1;
    +----+------+
    | id | name |
    +----+------+
    |  1 | AAA  |
    |  2 | BBB  |
    |  3 | CCC  |
    |  4 | DDD  |
    |  5 | FFF  |
    +----+------+
    5 rows in set (0.00 sec)
    

    但当我们按照当前查询到的内容对T1表进行修改时,却出现了奇怪的现象

    Current session:
    
    mysql> update t1 set name='AAAAA' where name='AAA';
    Query OK, 0 rows affected (0.00 sec)
    Rows matched: 0  Changed: 0  Warnings: 0
    
    mysql> select * from t1;
    +----+------+
    | id | name |
    +----+------+
    |  1 | AAA  |
    |  2 | BBB  |
    |  3 | CCC  |
    |  4 | DDD  |
    |  5 | FFF  |
    +----+------+
    5 rows in set (0.00 sec)
    
    mysql> update t1 set name='AAAAA' where name='AAAA';
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    mysql> select * from t1;
    +----+------+
    | id | name |
    +----+------+
    |  1 | AAAAA  |
    |  2 | BBB  |
    |  3 | CCC  |
    |  4 | DDD  |
    |  5 | FFF  |
    +----+------+
    5 rows in set (0.00 sec)
    
    

    从上面的实验可以看出,对T1表进行update的时候,并没有按照最开始执行查询的时候的数据静态版本中的内容来更新,而是按照表中实际数据内容来更新,也就是说,只有select操作才是严格意义上的可重复的,涉及表数据修改的操作不具有“可重复性”,是表在第一次被修改后,才对表施加了表级别的update和delete锁,从而实现的后续对该表修改的“可重复性”。

    相关文章

      网友评论

          本文标题:mysql repeatable read隔离级别探索

          本文链接:https://www.haomeiwen.com/subject/pfdxwhtx.html