实践理解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'。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了