关于MySQL可重复读的问题

一、可重复读

我们先看看现象,再分析原理。我的mysql版本是10.3.13。
在这里插入图片描述
下面是一张表,只有一条数据,并且我开启了事物
事务一:
事务一
事务二:
在这里插入图片描述
此时,事务二, 将sc + 1 执行下面的命令:

事务二, 将sc + 1

成功加1之后,实际上,数据库中sc肯定是2。

然后回到之前的客户端,再查一次:

查看事务一:
事务一

没毛病,sc还是1,果然是可重复读。有些人以为mysql的可重复读是通过行锁实现的,

从上面可以知道,肯定不是,如果是的话,第一次select * from demo的时候,id=1的记录就会加行锁,我都加行锁了,我还没提交,另外的事物是怎么update成功的。

结论就是mysql使用的MVCC(多版本并发控制),MVCC详解可以看:https://blog.csdn.net/whoamiyang/article/details/51901888

我们继续,我之前的第一个事物还没提交,不过提交之前,我也想加1;

对事务一的数据进行+1:
事务一更改

加完之后可以看到,锁等待超时。也就是说(事物二)在更新完后,会加行锁,这个应该比较好理解。事物中,刚开始查询的时候是不会加行锁的,但是当有更新操作之后,会加行锁,直到事物提交。

事务二提交:

事务二提交
此时事务一对数据重新进行更改:

事务一重新更改
事务一对数据更改成功:

在这里插入图片描述

注意:

可重复读的情况下 。当一个事务对数据库中的数据进行修改时,就对该条数据添加了 行锁。那么其他事务就不能对该条数据进行修改。
但是: 只是添加了 行锁.并不影响其他事务对其他数据的修改。

事务一:
数据库中有两条数据:

在这里插入图片描述
事务二:

在这里插入图片描述

更改事务一中的第一条数据:
在这里插入图片描述
可以看到已经更改成功了。

更改事务二中的第二条数据:

在这里插入图片描述
可以看到也更改成功了

将事务二的更改数据提交:

在这里插入图片描述

查询一下事务一的数据:

在这里插入图片描述
事务一的数据并没有变化

重新开启一个终端查看数据库:
在这里插入图片描述
数据库中的数据已经发生了变化…


http://hedengcheng.com/?p=771,http://hedengcheng.com/?p=844 这两篇博文详细的介绍了mysql中的这些问题,有兴趣可以读一读。

MySQL 可重复读(Repeatable Read)是指在一个事务中,查询的结果集是事务开始时刻的状态,即使其他事务对数据进行了修改,也不会影响当前事务中已经查询过的数据。 在可重复读的隔离级别下,MySQL 使用了多版本并发控制(MVCC)来实现。MVCC 在每个数据行上都会保存一个版本号,用于判断事务的可见性。当一个事务开始时,它会创建一个事务开始版本号,并在查询时只能看到该版本号之前的数据,而不会看到其他事务未提交的修改。 如果其他事务对数据进行了修改,但是还没有提交,那么当前事务中查询同样的数据时,会返回之前的版本。只有当其他事务将修改提交后,当前事务中的查询才会返回最新的数据。 需要注意的是,在可重复读隔离级别下,其他事务对数据的修改对当前事务是不可见的,但是当前事务对其他事务的修改是可见的。也就是说,如果当前事务修改了某个数据行,其他事务在查询该数据行时仍然会看到之前的值。 可以通过以下语句设置 MySQL 的隔离级别为可重复读: ``` SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; ``` 需要注意的是,可重复读虽然解决了脏(Dirty Read)和不可重复读(Non-Repeatable Read)的问题,但是仍然存在幻(Phantom Read)的情况。幻是指在一个事务中,多次查询同样的条件,但是结果集的行数不一致。为了解决幻问题,可以使用锁机制或者使用更高级别的隔离级别,如序列化(Serializable)隔离级别。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值