mysql事务怎么保证可重复读_实践理解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';

结果如下:

e3cfaaab7349a63616af01c923e00be9.png

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';

结果如下:

108cba85a3b0542ee0f94200d8f0362f.png

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

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

2dce46ab948286301117c6308c06e463.png

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

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

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

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

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

52f8cd313978ba0d5ace43e5edbddb4d.png

重新开启B事务:

BEGIN;

5.提交A事务:

COMMIT;

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

c76fd7746cac5f30dcb848e94b766e1a.png

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

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

6.提交B事务。

COMMIT;

然后再次查询:

850593eb63ec8deb51eda6973fe9da2e.png

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值