• 实践理解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'。

  • 相关阅读:
    ASP.NET获取服务器信息大全
    放在IIS上就报错
    WEB资源管理器
    用于主题检测的临时日志(925f1df8130a43969337cfd4cbeb06a4 3bfe001a32de4114a6b44005b770f6d7)
    如何正确的判断String是否为空
    直接输出另存
    查询聊天消息SQL语句!
    ShareSDKUndefined symbols for architecture arm64
    今天起航...
    UIScrollView方法 scrollRectToVisible: animated: 无效(不工作,无效果)的问题
  • 原文地址:https://www.cnblogs.com/expiator/p/12084882.html
Copyright © 2020-2023  润新知