读不提交,就是读脏数据,好理解,
读取已提交,可解决读取脏数据的问题,
可重复读取:Mysql的默认隔离级别由mvcc版本控制,会导致幻读问题。在不允许阅读的过程中,其他事务操作Update数据, 其他事务可能是insert,这是不可避免的;
序列化:事务串行,效率低下;
数据库事务有四个隔离级别,从低到高分别是Read uncommitted 、Read committed 、Repeatable read 、Serializable 。而且,在事务的并发操作中可能会出现脏读,不能重复,幻读。以下是他们的概念和联系的例子。
Read uncommitted
顾名思义,读未提交是指一个事务可以读取另一个未提交的数据。
例子:老板要给程序员发工资,程序员的工资是3.6万/月。但是发工资的时候,老板不小心按错了数字,按成3.9万/月。钱已经到了程序员的户口,但是事务还没有提交。这时,程序员去检查他这个月的工资,发现比平时多了3000元,觉得加薪很开心。但是老板及时发现不对劲,马上回滚差点提交的事情,把数字改成3.6万再提交。
分析:实际程序员的月薪仍然是36000英镑,但程序员看到的是39000英镑。他看到的是老板没有提交交易时的数据。这是肮脏的阅读。
Read committed
阅读提交,顾名思义,就是一个事务要等到另一个事务提交后才能读取数据。
例如:程序员用信用卡享受生活(当然,这张卡只有36000张)。当他付账时(程序员事务打开),收费系统提前检测到他的卡中有36000张,就在这个时候!!程序员的妻子必须把所有的钱都转移到家里,并提交。当收费系统准备扣除时,检查卡中的金额,发现没有钱(当然,第二次检查的金额必须等待妻子转移的金额提交)。程序员会很沮丧,显然卡里有钱…
分析:这是读取和提交。如果有事务更新数据,(UPDATE)操作时,读取操作事务需要等待更新操作事务提交后才能读取数据,解决脏读问题。但在这种情况下,一个事务范围内有两个相同的查询,但返回不同的数据,即不能重复。
Repeatable read
重复读取是指在开始读取数据(事务开始)时,不再允许修改操作
例:程序员拿着信用卡享受生活(当然卡里只有3.6万)。当他付账时(事务开始,其他事务的UPDATE不允许修改),收费系统提前检测到他的卡里有3.6万。这时,他的妻子不能转账。接下来,收费系统可以扣除。
分析:重复阅读可以解决不可重复阅读的问题。在这里,我们应该明白的是,不可重复的阅读对应于修改,即UPDATE操作。但也可能有幻读问题。因为幻读问题对应于插入INSERT操作,而不是UPDATE操作。
幻读什么时候出现?
例子:程序员有一天花了2000元,然后他的妻子去查看他今天的消费记录(扫描FTS,妻子的事务开始),看到真的花了2000元,此时,程序员花了1000元买了一台电脑,也就是说,新的INSERT消费记录,并提交。妻子打印程序员的消费记录清单(提交妻子事务)时,发现花费12000元,似乎有幻觉,这就是幻读。
如何解决幻读问题?Serializable
Serializable 序列化
Serializable 它是最高的事务隔离级别。在此级别下,可以避免脏读、不重复读和幻读。然而,这种事务隔离级别效率低下,消耗数据库性能,一般不使用。
四个隔离级别可能导致的问题:
1、Serializable (串行化):最严格的级别,事务串行执行,资源消耗最大;
2、REPEATABLE READ(重复读) :它确保一个事务不会修改已被另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”,但不能避免“幻读”,但带来了更多的性能损失。
3、READ COMMITTED (提交读):大多数主流数据库的默认事务级别确保一个事务不会读取修改但未提交的另一个平行事务的数据,避免“脏读取”,但不能避免“幻读”和“不可重复读取”。该级别适用于大多数系统。
4、Read Uncommitted(未提交阅读) :即使事务中的修改没有提交,其他事务也可以看到,这将导致“脏读”、“幻读”和“不能重复读取”。
通俗解释:
脏阅读:所谓脏阅读实际上是在其他事务回滚之前阅读脏数据。例如,在事务B执行过程中修改了数据X。在提交之前,事务A读取了X,但事务B回滚,因此事务A形成了脏阅读。
也就是说,当前事务读取的数据是其他事务想要修改但没有成功修改的数据。
不要重复阅读:事务A首先读取数据,然后执行逻辑。当事务B更改数据时,当事务A再次读取数据时,发现数据不匹配,即所谓的不可重复阅读。
也就是说,当前事务首先读取数据,然后再读取的数据是其他事务成功修改的数据,导致两次读取的数据不匹配,这照顾了不可重复读取的语义。
幻读:事务A首先根据条件索引获得N个数据,然后事务B更改N个数据以外的M个数据或添加符合事务A搜索条件的M个数据,导致事务A再次搜索发现N+M个数据,产生幻读。
也就是说,当前事务读取第一次获得的数据与后来读取的数据条目不一致。