zoukankan      html  css  js  c++  java
  • SELECT ... LOCK IN SHARE MODE和SELECT ... FOR UPDATE locks在RR模式下可以看到最新的记录

    14.5.2.4 Locking Reads  锁定读:
    
    如果你查询数据然后插入或者修改相关数据在相同的事务里, 常规的SELECT 语句不能给予足够的保护。
    
    其他事务可以修改或者删除你刚查询相同的记录,InnoDB 支持2个锁定读的类型提供额外的安全:
    
    
    /*******************
    
    测试MYSQL RR 的重复读:
    
    CREATE TABLE `t3` (
      `sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号',
      `phoneNo` int(11) DEFAULT NULL,
      PRIMARY KEY (`sn`));
    
    mysql> show create table t3;
    +-------
    
    +------------------------------------------------------------------------------------------------------------------------------------------------------------
    
    --------------------+
    | Table | Create Table                                                                                                                                        
    
                               |
    +-------
    
    +------------------------------------------------------------------------------------------------------------------------------------------------------------
    
    --------------------+
    | t3    | CREATE TABLE `t3` (
      `sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号',
      `phoneNo` int(11) DEFAULT NULL,
      PRIMARY KEY (`sn`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8     |
    +-------
    
    +------------------------------------------------------------------------------------------------------------------------------------------------------------
    
    --------------------+
    1 row in set (0.00 sec)
    
    
    Session 1:
    mysql> start transaction;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> select * from t3;
    +----+---------+
    | sn | phoneNo |
    +----+---------+
    |  1 |      11 |
    |  2 |      22 |
    +----+---------+
    2 rows in set (0.00 sec)
    
    mysql> select * from t3;
    +----+---------+
    | sn | phoneNo |
    +----+---------+
    |  1 |      11 |
    |  2 |      22 |
    +----+---------+
    2 rows in set (0.00 sec)
    
    
    Session 2:
    
    Database changed
    mysql> delete from t3 where sn=2;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> commit;
    Query OK, 0 rows affected (0.00 sec)
    
    
    此时session 1看到的还是2条 表明RR是重复读
    
    
    
    1.SELECT ... LOCK IN SHARE MODE 设置一个共享锁锁定在任何你要读的记录,其他session 只能读取记录,
    
    因为不能修改它们直到你的事务提交。
    
    如果任何其他记录被其他事务改变 没有被提交,你的查询等待直到那个事务借宿 然后使用最新的数据
    
    
    mysql> select * from t3;
    +----+---------+
    | sn | phoneNo |
    +----+---------+
    |  1 |      11 |
    |  2 |      22 |
    +----+---------+
    2 rows in set (0.00 sec)
    
    mysql> select * from t3 LOCK IN SHARE MODE;
    
    
    
    
    
    
    
    
    +----+---------+
    | sn | phoneNo |
    +----+---------+
    |  1 |      11 |
    |  2 |      99 |
    +----+---------+
    2 rows in set (4.78 sec)
    
    
    看到的是最新的数据:
    
    
    mysql> select * from t3;
    +----+---------+
    | sn | phoneNo |
    +----+---------+
    |  1 |      11 |
    |  2 |      22 |
    +----+---------+
    2 rows in set (0.00 sec)
    
    mysql> select * from t3 LOCK IN SHARE MODE;
    +----+---------+
    | sn | phoneNo |
    +----+---------+
    |  1 |      11 |
    |  2 |      99 |
    +----+---------+
    2 rows in set (0.00 sec)
    
    
    
    2.
    
    
    mysql> select * from t3 where sn=2 for update   --看到的也是最新的记录
        -> ; 
    
    +----+---------+
    | sn | phoneNo |
    +----+---------+
    |  2 |      99 |
    +----+---------+
    1 row in set (4.26 sec)
    
    mysql> 
    mysql> select * from t3;
    +----+---------+
    | sn | phoneNo |
    +----+---------+
    |  1 |      11 |
    |  2 |      22 |
    +----+---------+
    2 rows in set (0.00 sec)
    
    
    
    对于所有搜索遇到, SELECT ... FOR UPDATE locks 锁定记录和任何相关的index entries,
    
    
    相当于你执行一个update语句对于那些记录。
    
    
    其他事务是被堵塞的来更新那些记录,做 SELECT ... LOCK IN SHARE MODE, 
    
    或者从读取的数据在某些事务隔离级别。
    
    
    一直读忽略任何锁设置在记录上(老的记录不能被锁定,它们是应用undo log重构的)
    
    
    
     当 LOCK IN SHARE MODE and FOR UPDATE 查询的索引锁是被释放放事务是被提交或者回滚
    
    
    锁定记录用于更新使用SELECT FOR UPDATE 只使用与当autocommit 被关闭(或者开始事务使用START TRANSACTION or by setting autocommit to 0.
    
    如果自动提交启用,匹配的记录不会被锁定)

  • 相关阅读:
    Spring Boot 无侵入式 实现 API 接口统一 JSON 格式返回
    Java8 Stream:2万字20个实例,玩转集合的筛选、归约、分组、聚合
    排名前 16 的 Java 工具类
    万字详解,JDK8 的 Lambda、Stream 和日期的使用详解
    这样规范写代码,同事直呼“666”
    Java多线程高并发学习笔记——阻塞队列
    零散的MySQL基础总是记不住?看这一篇就够了!
    Java 中自定义注解及使用场景
    最简单的6种防止数据重复提交的方法!
    选择数据库联系人【选择之后将不在列表】
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13350125.html
Copyright © 2011-2022 走看看