MySQL事务之不可重复读问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sun8112133/article/details/89739475

版权声明:本文为 小异常 原创文章,非商用自由转载-保持署名-注明出处,谢谢!
本文网址:https://blog.csdn.net/sun8112133/article/details/89739475








在事务的并发操作中,也就是多个事务同时对同一组数据进行操作时,可能会出现脏读、不可重复读、幻读这三个问题,本篇博客就来为大家演示不可重复读问题。

一、不可重复读概述

不可重复读 就是一个事务读到另一个事务修改后并提交的数据(update)。在同一个事务中,对于同一组数据读取到的结果不一致。比如,事务B 在 事务A 提交前读到的结果,和在 事务A 提交后读到的结果可能不同。不可重复读出现的原因就是由于事务并发修改记录而导致的。

隔离级别 有四种,分别是:读未提交、读已提交、可重复读、序列化。
  读未提交: Read Uncommitted,顾名思义,就是一个事务可以读取另一个未提交事务的数据。最低级别,它存在3个问题(脏读、不可重复读、幻读)。
  读已提交: Read Committed,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。 它解决了脏读问题,存在2个问题(不可重复读、幻读)。
  可重复读: Repeatable Read,就是在开始读取数据(事务开启)时,不再允许修改操作 。它解决了脏读和不可重复读,还存在1个问题(幻读)。
  序列化: Serializable,序列化,或串行化。就是将每个事务按一定的顺序去执行,它将隔离问题全部解决,但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

大多数数据库默认的事务隔离级别是 Read Committed,比如 SQL Server , Oracle。但 MySQL 的默认隔离级别是 Repeatable Read。

1、事例

程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他买单时(程序员事务开启),收费系统事先检测到他的卡里有3.6万,就在这个时候!!程序员的妻子要把钱全部转出充当家用,并提交。当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了(第二次检测金额当然要等待妻子转出金额事务并提交完)。程序员就会很郁闷,明明卡里是有钱的…

2、分析

在这个事例中,涉及到了两个事务(程序员事务和妻子事务),当程序员事务开启时,收费系统读取程序员卡里钱的操作还没完成,此时妻子这个事务就将卡里的钱进行了转账,即对数据进行了修改,导致收费系统两次读取到的数据不一样。出现了一个事务范围内两个相同的查询却返回了不同数据,这就是不可重复读,这是由于数据更新导致的,不能重复读取相同的数据。

事务的不可重复读


二、演示不可重复读

1、新建一个数据库(bank库),并准备一张表(account表)

1、数据库和数据表

2、打开两个窗口,并分别设置自动提交方式为off

show variables like 'autocommit';   – 查看当前的自动提交是否开启

set autocommit = off;   – 将自动提交关闭

扫描二维码关注公众号,回复: 6089762 查看本文章
2、取消自动提交(A窗口)
2、取消自动提交(B窗口)

3、将A窗口的隔离级别设置成 “读已提交”

select @@tx_isolation;   – 查询当前的隔离级别

set session transaction isolation level read committed;   – 设置当前会话隔离级别为“读已提交”

3、设置隔离级别

4、两个窗口分别开启事务

start transaction;   – 开启事务

4、开启事务

5、在B窗口更改数据,并提交事务

use bank   – 切换到bank数据库

update account set money = money - 100 where id = 1;   – 修改account表中id为1的money字段数据

commit;   – 提交事务

5、更改数据

6、分别在数据库和A窗口中查看数据

select * from account;   – 查看account中的全部数据

6、查看数据(数据库)
6、查看数据(A窗口)

大家会发现数据库和A窗口中的数据都发生了改变,因为B窗口已经提交了事务,所以数据库中的数据发生改变,是属于正常现象。但是这种事务的隔离性似乎不是太好(事务的隔离性是一个事务的执行,不受其他事务的干扰),你看,B窗口提交了事务,影响到了A窗口中数据,这种隔离级别虽然解决了 ”脏读“ 问题,但是还会引发 ”不可重复读““幻读” 问题,有关 “幻读” 的问题请参考后续博客。


有关事务的知识可以参考我之前写的博客《【Spring4.0笔记整理十七】Spring事务详解》【Spring4.0笔记整理十八】Spring事务管理详解


博客中若有不恰当的地方,请您一定要告诉我。前路崎岖,望我们可以互相帮助,并肩前行!



猜你喜欢

转载自blog.csdn.net/sun8112133/article/details/89739475