数据库中四种隔离级别导致的并发问题

为了故事的顺利发展,我们需要创建一个表:
CREATE TABLE hero ( number INT, name VARCHAR(100), country varchar(100), PRIMARY KEY (number) ) Engine=InnoDB CHARSET=utf8;
小贴士: 注意我们把这个hero表的主键命名为number,而不是id,主要是想和后边要用到的事务id做区别,大家 不用大惊小怪哈~
然后向这个表里插入一条数据:
INSERT INTO hero VALUES(1, ‘刘备’, ‘蜀’);
现在表里的数据就是这样的:
mysql> SELECT * FROM hero;
±-------±-------±--------+
| number | name | country |
±-------±-------±--------+ |
1 | 刘备 | 蜀 |
±-------±-------±--------+
1 row in set (0.00 sec)
24.2 事务隔离级别 我们知道 MySQL 是一个 客户端/服务器 架构的软件,对于同一个服务器来说,可以有若干个客户端与之连接, 每个客户端与服务器连接上之后,就可以称之为一个会话( Session )。每个客户端都可以在自己的会话中向服 务器发出请求语句,一个请求语句可能是某个事务的一部分,也就是对于服务器来说可能同时处理多个事务。在 事务简介的章节中我们说过事务有一个称之为 隔离性 的特性,理论上在某个事务对某个数据进行访问时,其他 事务应该进行排队,当该事务提交之后,其他事务才可以继续访问这个数据。但是这样子的话对性能影响太大, 我们既想保持事务的 隔离性 ,又想让服务器在处理访问同一数据的多个事务时性能尽量高些,鱼和熊掌不可得 兼,舍一部分 隔离性 而取性能者也。
24.2.1 事务并发执行遇到的问题 怎么个舍弃法呢?我们先得看一下访问相同数据的事务在不保证串行执行(也就是执行完一个再执行另一个)的 情况下可能会出现哪些问题:
脏写( Dirty Write )
如果一个事务修改了另一个未提交事务修改过的数据,那就意味着发生了 脏写 ,示意图如下:
在这里插入图片描述
如上图, Session A 和 Session B 各开启了一个事务, Session B 中的事务先将 number 列为 1 的记录的 name 列更新为 ‘关羽’ ,然后 Session A 中的事务接着又把这条 number 列为 1 的记录的 name 列更新为 张飞 。如果之后 Session B 中的事务进行了回滚,那么 Session A 中的更新也将不复存在,这种现象就称 之为 脏写 。这时 Session A 中的事务就很懵逼,我明明把数据更新了,后也提交事务了,怎么到后说 自己啥也没干呢? 脏读( Dirty Read )
如果一个事务读到了另一个未提交事务修改过的数据,那就意味着发生了 脏读 ,示意图如下:
在这里插入图片描述

如上图, Session A 和 Session B 各开启了一个事务, Session B 中的事务先将 number 列为 1 的记录的 name 列更新为 ‘关羽’ ,然后 Session A 中的事务再去查询这条 number 为 1 的记录,如果du到列 name 的 值为 ‘关羽’ ,而 Session B 中的事务稍后进行了回滚,那么 Session A 中的事务相当于读到了一个不存在 的数据,这种现象就称之为 脏读 。 不可重复读(Non-Repeatable Read)
如果一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交 后,该事务都能查询得到新值,那就意味着发生了 不可重复读 ,示意图如下:
在这里插入图片描述

如上图,我们在 Session B 中提交了几个隐式事务(注意是隐式事务,意味着语句结束事务就提交了),这 些事务都修改了 number 列为 1 的记录的列 name 的值,每次事务提交之后,如果 Session A 中的事务都可 以查看到新的值,这种现象也被称之为 不可重复读 。 幻读(Phantom)
如果一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先 的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来,那就意味着发生了 幻读 ,示意图如 下:
在这里插入图片描述

如上图, Session A 中的事务先根据条件 number > 0 这个条件查询表 hero ,得到了 name 列值为 ‘刘 备’ 的记录;之后 Session B 中提交了一个隐式事务,该事务向表 hero 中插入了一条新记录;之后 Session A 中的事务再根据相同的条件 number > 0 查询表 hero ,得到的结果集中包含 Session B 中的事 务新插入的那条记录,这种现象也被称之为 幻读 。
有的同学会有疑问,那如果 Session B 中是删除了一些符合 number > 0 的记录而不是插入新记录,那 Session A 中之后再根据 number > 0 的条件读取的记录变少了,这种现象算不算 幻读 呢?明确说一下, 这种现象不属于 幻读 , 幻读 强调的是一个事务按照某个相同条件多次读取记录时,后读取时读到了之前没 有读到的记录。
小贴士: 那对于先前已经读到的记录,之后又读取不到这种情况,算啥呢?其实这相当于对每一条记录都 发生了不可重复读的现象。幻读只是重点强调了读取到了之前读取没有获取到的记录。
不可重复读的和幻读很容易混淆,不可重复读侧重于修改或删除,幻读侧重于新增。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值