MySQL数据库的脏读、不可重复读、幻读

多个事务同时操作同一个数据库的相同数据时,可能会导致事务的并发问题。

  • 脏读:一个事务读取了其他事务还没有提交的数据,读到的是其他事务“更新”的数据。
  • 不可重复读:一个事务多次读取,结果不一样。例如下订单,查询库存是1,另一个事务更新库存为100并提交事务,然后再去进行第二次的查询,查询结果却变成了100。
  • 幻读:一个事务读取了其他事务还没有提交的数据,只是读到的是其他事务“插入”的数据。

可以通过设置隔离级别来解决并发问题。

  • read uncommitted:读未提交。
  • read committed:读已提交。
  • repeatable read:可重复读。需要解决在当前事务查询已提交的结果不变,如果再重新开一个事务,才显示已提交的新的数据。这样就解决了一次事务多次读取的数据是一致的。
  • serializable:串行化。例如,淘宝搜索商品,搜索时暂时没有商品,等到后台加载完数据,其实是可以显示搜索结果的,但是因为串行化隔离性特别好,所以在当前事务,即使是刷新也无法显示,必须等到关闭浏览器重新打开,也就是重新打开一个新的事务才会显示。搜索商品要的是实时刷新,所以没有必要使用串行化隔离级别。

read uncommitted(读未提交)

首先创建一个MySQL会话连接,并通过select @@tx_isolation;查看当前隔离级别。默认的隔离级别为可重复读
在这里插入图片描述

设置隔离级别为最低的read uncommitted,此时事务可能出现脏读、不可重复读、幻读。
在这里插入图片描述

开启事务,将张三修改为zhangsan,但是并没有commit提交事务。

在这里插入图片描述
重新开启一个MySQL会话连接,并将隔离级别也设置为read uncommitted
在这里插入图片描述
即使没有提交事务,但当从新的会话去查询account表的数据时,张三已经变成了zhangsan
在这里插入图片描述
如果之前的事务执行了回滚
在这里插入图片描述
再去查询数据时就会出现读取未被其它事务提交的数据,可能会出现脏读不可重复读幻读的问题。
在这里插入图片描述

read committed(读已提交)

设置隔离级别为read committed
在这里插入图片描述
开启事务,将张三修改为zhangsan,但是并没有commit提交事务。
在这里插入图片描述

在另一个新的会话设置隔离级别为read committed,之前的事务没有提交,但是查询数据发现还是张三,并没有变成zhangsan
在这里插入图片描述
之前的事务执行提交
在这里插入图片描述
另一个会话再去查询数据时,张三变成了zhangsan
在这里插入图片描述
这样就避免了脏读,但是在一次事务多次查询中出现了不一样的结果,所以不能避免不可重复读和幻读。

在这里插入图片描述

repeatable read(可重复读)

设置隔离级别为repeatable read,开启事务,将张三修改为zhangsan,但是并没有commit提交事务。
在这里插入图片描述
另一个新的会话也将隔离级别设置为repeatable read,并查询数据,张三并没有变成zhangsan
在这里插入图片描述
之前的事务执行提交
在这里插入图片描述
但是另一个会话执行查询命令,即使之前的事务提交,结果还是张三,并没有变成zhangsan
在这里插入图片描述
只有当结束事务,重新开启一个新的事务进行查询时,才会查询到变更后的数据
在这里插入图片描述
这样就避免了脏读、不可重复读,但是不能避免幻读,比如下面就有可能出现幻读。

重新开启一个事务,将表中的所有username都更新为aaa,表中的数据此时只有两条,但是在点击回车的之前,有另一个会话执行了一个事务,这个事务在表中有插入了一条数据,然后再去执行之前的事务,会发现有3条记录被修改。这就产生了幻读
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

serializable(串行化)

将隔离级别设置为serializable
在这里插入图片描述
开启一个新的事务,将张三修改为zhangsan,但是并没有点击回车执行
在这里插入图片描述
此时在另一个会话执行插入数据操作,点击回车,此时会发现命令并没有执行,而是发生了阻塞,相当于在等待另外一个事务释放锁。
在这里插入图片描述
之前的事务执行提交命令,才会成功执行插入操作
在这里插入图片描述

这样序列化就避免了幻读,但是虽然序列化可以避免所有的并发问题,但是性能十分低下。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值