脏读幻读不可重复读形象比喻

讲知识最好是深入浅出。

把深奥的东西用浅显的道理讲出来。

所谓浅显就是人们容易感知,人们熟悉它,了解它,生活中能遇到它,形容它。

今天讲讲脏读,不可重复读,幻读,这几个数据库事务里一定会提起来的词语。

讲这个之前先把4个隔离级别熟悉一下。

然后我讲下怎么来记忆这4个级别,很多人可能知道但是老记不住或者记混了。

我们把四个级别按照隔离程度排序1234.

先记3

3是啥

找一个恶趣味

3P

就代表着 单词里有 p

Repeatable

可重复读

 

然后1是啥

1是最低

最弱

最无能

无能就是 unable

un这个 un那个 un就是无能

Uncommitted 未提交就是1

 

2序号大点

牛逼点

比无能要有能一点

就不是Un了

就能 commit了

 

4是串行化

4就是死嘛

死就是S

所以有一个

Serializalabl

这样1234都容易记住了。

 

然后我们来说一些场景来分别描述脏读,不可重复读,幻读。

假如有一张表  account

表里有一条数据 代表ID=1的账号有1000元钱

#1先看看脏读的场景

假设有两个用户A B 同时在连接数据库在做操作

用户A

set session transaction isolation level read uncommitted;

start transaction;

select * from account;

用户B

set session transaction isolation level read uncommitted;

start transaction;

update account set account=account-200 where id = 1;

在如上的这种SQL的场景里

可能发生什么事情呢?

用户B执行到一半反悔了 回滚了

用户A得到了一个800

这个800是个假800

他认为账号里有800元 其实不是

他读的是一个尚未提交的数据 是一个半路上的数据

举一个军队里的形象的例子:你作为一个土匪窝里的小兵,你从山下过来山上问今天晚上的口令是什么,而口令正在讨论中,二当家说的口令就定为“整个西班牙晴空万里”吧,你走到大营门口问站岗的王二狗,王二狗就听到了这句,然后告诉你这就是今晚的口令,你屁颠屁颠的下山了,结果二当家说完了以后,大当家上去就是一个耳掴子,什么玩意,西班牙西班牙的,今天的口令叫“天王盖地虎”,你不知道后来发生的事情,晚上巡夜的时候,口令错误,被打死了,你临死前感慨,王二狗真TM脏啊,这就是脏读,读了尚未决定的值。

 

#2再来看看不可重复读

用户B

set session transaction isolation level read committed;

start transaction;

update account set account=account-200 where id=1;

用户A

set session transaction isolation level read committed;

start transaction;

select * from account;  //读一次

select * from account;  //又读一次

select * from account; //再读一次

在如上的场景里可能发生什么事呢

用户A在同一个事务里

第一次读是1000

第二次读是800

读出了不同的结果,A就懵逼了。

注意是同一个事务哈,不能再往下分割了。

下一个事务再来,人家发生了变化是正常的。

还是举一个例子,你是作为一个土匪窝里的小兵,你从山下过来山上问今天晚上的口令是什么,站岗的王二狗说,是“小鸡炖蘑菇”,然后风有些大,你想确认一下,说道:Pardon? can you say again?

王二狗说是“清风扶杨柳”,这个时候你怒了,“你小子玩儿我呢吧?刚才说的是这个吗”,问一遍一个答案,这就是不可重复读。

 

#3再来看看幻读。

用户A

set autocommit = 0;

set session transaction isolation level repeatable read;

start transaction;

select * from account;

select * from account;

select * from account;

INSERT INTO `baseinfo`.`account` (`id`, `account`) VALUES ('2', '1000.00');

COMMIT;

用户B

set autocommit = 0;

set session transaction isolation level repeatable read;

start transaction;

update account set account=account-200 where id=1;

INSERT INTO `baseinfo`.`account` (`id`, `account`) VALUES ('2', '1000.00');

COMMIT;

这里可能发生什么场景呢。

用户A先查询后插入,非常正经,非常正派的做法。

结果呢,因为用户B给插入了ID=2,造成A老是插不进去。

用户A疯了 我查询了3次,数据表里没有id为2的数据啊,我怎么就插入不进去呢。

举一个实际的例子,两拨土匪打仗了,你作为一个土匪窝里的小兵,然后你去一个山头上架设电话线,为了保证安全,去之前你首先问一次,那个山头上有没有敌人啊,回答说没有,不放心你又问了一次,那个山上有没有敌人啊,回答说没有,最后马上要上山了,你又问一次,有没有敌人啊,回答说没有,结果你刚爬上山,一梭子子弹打过来,给你打残废了。这个时候你脑子蒙蒙的,说道TM的老子是幻听了吗,不是说的没有敌人吗?

这就是幻读。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值