- 一、脏读、不可重复读、幻读
- (1)脏读
- (2)不可重复读
- (3)幻读
- 二、数据库隔离级别
- (1)读未提交
- (2)读已提交
- (3)可重复读
- (3)可串行化
简单来说,脏读就是读取未提交数据。
- A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行回滚 *** 作,那么A事务读取到的数据就是脏数据。
- 就好像原本的数据比较干净、纯粹,此时由于B事务更改了它,这个数据变脏了,这个时候A事务立即读取了这个脏数据,但事务B良心发现,又用回滚把数据恢复成原来的样子,而事务A却什么都不知道,最终结果就是事务A读取了此次的脏数据,称为脏读。
简单来说,就是前后多次读取,数据内容不一致。
事务A在执行读取 *** 作,由整个事务A比较大,前后读取同一条数据需要经历很长的时间 。
- 事务A第一次读取数据,比如此时小明的年龄为20岁,事务B执行更改 *** 作,将小明的年龄更改为30岁,事务A第二次读取到小明的年龄时,发现其年龄是30岁,和之前的数据不一样了。
- 然而按照正确逻辑,事务A前后两次读取到的数据应该一致。
简单来说就是,前后多次读取,数据总量(就是数据的个数,而不是内容)不一致。
事务A在执行读取 *** 作,需要两次统计数据的总量,前一次查询数据总量后,此时事务B执行了新增数据的 *** 作并提交后,这个时候事务A读取的数据总量和之前统计的不一样,就像产生了幻觉一样,平白无故的多了几条数据,成为幻读。
二、数据库隔离级别有四种隔离级别,分别是:
- 读未提交(Read uncommitted)
- 读已提交(Read committed)
- 可重复读(Repeatable read)
- 可串行化(Serializable)
四种级别用来解决数据库 *** 作中产生的各种问题。
(1)读未提交- 这种隔离级别最低,甚至允许你脏读…
- 在这种隔离级别下,所有事务能够读取其他事务未提交的数据。读取其他事务未提交的数据,会造成脏读。因此在该种隔离级别下,不能解决脏读、不可重复读和幻读。
读未提交可能会产生脏读的现象,那么怎么解决脏读呢?那就是使用读已提交。
(2)读已提交- 在这种隔离级别下,所有事务只能读取其他事务已经提交的内容。能够彻底解决脏读的现象。
- 但在这种隔离级别下,还是会出现一个事务的前后多次的查询中却返回了不同内容的数据的现象,也就是出现了不可重复读。
注意,这是大多数数据库系统默认的隔离级别,例如Oracle和SQL Server,但mysql不是。
这种隔离级别可能会产生不可重复读的现象,我们可以使用可重复读。
(3)可重复读- 在这种隔离级别下,所有事务前后多次的读取到的数据内容是不变的。
- 也就是某个事务在执行的过程中,不允许其他事务进行update *** 作,但允许其他事务进行add *** 作(数据库的数据个数可以被增加),造成某个事务前后多次读取到的数据总量不一致的现象,从而产生幻读。
注意,这才是mysql的默认事务隔离级别,另外,mysql在可重复读的级别上,使用间隙锁的方式就已经解决了幻读的问题
可重复读依然会产生幻读的现象,此时我们可以使用串行化来解决。
(3)可串行化- 在这种隔离级别下,所有的事务顺序执行,所以他们之间不存在冲突,从而能有效地解决脏读、不可重复读和幻读的现象。
- 但是安全和效率不能兼得,这样事务隔离级别,会导致大量的 *** 作超时和锁竞争,从而大大降低数据库的性能,一般不使用这样事务隔离级别。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)