• 实践理解Mysql事务隔离级别之可重复读


    可重复读

    Mysql的事务隔离级别,默认是可重复读(repeatable-read)。

    以下通过具体的sql操作去理解可重复读。

    建表

    CREATE DATABASE test;
    
    USE test;
    
    CREATE TABLE `t_order` (
      `fid` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键,自增id',
      `forder_id` varchar(35) NOT NULL COMMENT '订单号,唯一',
      `fpay_status` varchar(15) DEFAULT '00' COMMENT '00:未支付,01:支付成功,02:支付失败,03:已下单,04:申请退款,05:退款成功,06:退款失败,10:订单关闭',
      PRIMARY KEY (`fid`),
      UNIQUE KEY `forder_id` (`forder_id`)
      )   ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单表';
    	
    SELECT * FROM t_order;
    

    多个事务操作

    如果使用的是navicat,可以新建两个"查询"窗口,模拟A、B两个事务。

    1.在两个窗口,分别执行以下语句,开启事务:

    BEGIN;
    

    2.查询数据:

    SELECT * FROM t_order WHERE forder_id='abc';
    

    结果如下:

    3.在A事务中,执行update语句,然后再次查询:

    UPDATE t_order SET fpay_status='01' WHERE forder_id='abc' AND fpay_status='00';
    
    SELECT * FROM t_order WHERE forder_id='abc';
    

    结果如下:

    在A事务中,执行update后,fpay_status变为'01'

    4.在B事务中,查询数据,结果如下:

    由于A事务还没有提交,在可重复读的事务隔离级别下,B事务中的数据还是初始的值'00'。

    接着,在B事务中,执行update语句,如下:

    UPDATE t_order SET fpay_status='01' WHERE forder_id='abc' AND fpay_status='00';
    
    

    发现B事务会阻塞,原因是A事务执行update语句时加了行锁。

    一段时间后,B事务会超时。

    重新开启B事务:

    BEGIN;
    

    5.提交A事务:

    COMMIT;
    

    然后,在B事务中查询,结果如下:

    发现B事务中的fpay_status还是初始的值'00',这是因为:

    在可重复读的事务隔离级别下,读取的是快照数据,总是读取当前事务开始时的行数据版本。

    6.提交B事务。

    COMMIT;
    

    然后再次查询:

    提交事务后,查询到的就是最新的数据了,fpay_status为'01'。

  • 相关阅读:
    1722 最优乘车 1997年NOI全国竞赛
    5969 [AK]刻录光盘
    tarjan算法讲解
    求有向图的强连通分量个数 之 Kosaraju算法
    信使
    1405 奶牛的旅行
    P1828 香甜的黄油 Sweet Butter
    洛谷P2235 [HNOI2002]Kathy函数
    「BZOJ1010」[HNOI2008] 玩具装箱toy(斜率优化)
    BZOJ 1974 [Sdoi2010] auction 代码拍卖会(数位dp)
  • 原文地址:https://www.cnblogs.com/expiator/p/12084882.html
Copyright © 2020-2023  润新知