巧用西游记中的情节来理清数据库中的脏读、不可重复读、幻读
鄙人刚学完数据库中的事务,因为偶然关系看到西游记中唐僧师徒路过车迟国斗法的一个小片段,灵感由此而来。
如果本人初学数据库,如果描述的有什么缺点,还请各位多多指教。在本文中,我都会先给出脏读、不可重复读、幻读的概念或者说是含义。读者可以先看例子再看最开始我写的定义会很好理解。
首先来说脏读:
这个是一个概念性的:对于两个事务 T1, T2, T1 读取了已经被 T2 更新但还 没有被提交的字段之后, 若 T2 回滚, T1读取的内容就是临时且无效的.
例子:(看唐僧猜蟠桃)
在唐僧和鹿力大仙比试隔空猜物这个游戏中,女王–车迟国皇帝的媳妇,将一个蟠桃房子柜子中,让双方猜物(也就好比数据库中的事务读取数据),此时柜子门时锁住的(你不知道数据是什么),鹿力大仙施法并看到是个蟠桃,悟空给唐僧说:我施法进去将蟠桃吃了只剩桃核,到时候师傅你就说桃核,由于情况紧急悟空进去还没来得及吃(这时将事务进行数据修改比作悟空进到柜子里,吃桃子比作事务提交),国王就问柜子里是什么?唐僧给出了桃核的答案,因为此时悟空只是进到柜子里但还没有吃蟠桃------(也就是事务只修改了数据还没提交),此时唐僧就是脏读,唐僧获取的这个数据是无效的也是不对的,因为悟空可以使坏,进到柜子里(修改了数据),没有去吃蟠桃的这个期间(事务还没有被提交)。
其次不可重复读:
对于两个事务T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段之后, T1再次读取同一个字段, 值就不同了.
例子:(看鹿力大仙去猜蟠桃)
还是唐僧和鹿力猜蟠桃的游戏,这次前缀不叙述了,女王还是将一个蟠桃放到柜子里,鹿力大仙先猜(即读取了数据)即蟠桃,悟空进到柜子将蟠桃吃了,只留下桃核,唐僧读取数据为蟠桃,然后女王打开柜门,即代表鹿力再一次读取了数据,可是却为桃核(即本次读取的数据和第一次读取的数据不一样),这就是不可重复读。
最后幻读:(继续看鹿力猜蟠桃)
对于两个事务T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插入了一些新的行之后, 如果 T1 再次读取同一个表, 就会多出几行.
还是女王还是将一个蟠桃放到柜子里,鹿力大仙还是先猜为蟠桃(首次读取数据),接着悟空还是继续进到柜子里,这次悟空不能动蟠桃(如果进行修改数据就变为了脏读,即只能进行插入行),所以悟空变出一个苹果也放在柜子中,所以当女王打开柜门,即鹿力第二次读取数据,发现除了蟠桃,还多了个苹果,鹿力觉得可能出现了幻觉,这就是幻读。
处理脏读、不可重复读、幻读的方法
采用事务隔离机制来进行解决:(以下所说是指事务A和事务B操作的是同一个表中的数据)
read_uncommitted(读未提交):事务A可以读取事务B正在修改还没提交的数据,这会导致脏读、不可重复读、幻读都会出现。
read_committed(读已提交):事务A不可以读取事务B正在修改还没提交的数据,除非事务B提交这会导致不可重复读、幻读都会出现,但避免了脏读。
repearable_read(可重复读):事务A正在进行读出数据时,事务B不可进行修改表中数据,但可以插入新的行,可以有效地避免脏读、不可重复读,但无法避免幻读。
serializable(串行化):事务A正在进行读取表中数据时,事务B不可对表中数据进行任何操作(此时事务B进入等待状态),只有事务A结束,事务B才可以对表中数据进行操作。
想重温经典的可以点但这里去看看,剧集中鹿力大仙猜蟠桃是一个不可重复读。
西游记车迟国斗法猜蟠桃在第三十八分15秒
第一次写博客,如果有什么问题还望大家留言或评论交流,最后谢谢你的浏览。