事务的四种隔离级别(超详细!!!)

Posted 后季暖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事务的四种隔离级别(超详细!!!)相关的知识,希望对你有一定的参考价值。

网上看了很多的解读,都只回答了概念的问题,再加上脏读、幻读等概念的混淆,很多人都一头雾水,没有真正地理解,所以还是要演示一下以便更好地理解和记忆。

一、首先演示第一个级别,也是安全系数最低的级别,就是读未提交(read uncommitted)

 开两个cmd窗口:

 我们发现,右边窗口已经开启事务,insert添加了一行数据,(因为开启了事务 所以不会自动提   交)

 所以并没有提交 ,但左边能读出来你添加的这行数据了。这就是读未提交。

 脏读就是假如现在右边目前执行的事务不想要了,回滚了,也就是不想添加这一行了,那么左边   读取的数据还是有添加的这一行,这就是脏读。 

二、读已提交(read committed)

读已提交,顾名思义,就是可以读取到已经提交事务的内容。

这个级别很显然,当你只有提交事务的时候,别的地方才能读取到你的操作。

 commit以后,左边就能读到了。

 但是!这样的话,就不可重复读了!因为比如1时刻,你这个事务读取这个表的数据是张三,

2时刻另外有一个事务把张三改成了李四,并且提交了该事务。这样在你原来那个事务再次查询的

时候(4时刻),读到的就是李四了,导致两次读取结果不一致。

三:这样我们就引入了第三种事务级别:可重复读(repeatable read)

比如此时表中只有一条数据,id为1,name为张三。

一时刻,我们在左边表开启一个事务,查询这个表id为2的数据,发现没有。

二时刻,我们在右边表开启一个事务,并添加一条id=2,name=‘王五’的数据,并提交。

三时刻,我们在左表再次查询id为2的数据,发现还是没有,这就是幻读,读到的是幻象。

此时我们在左边表更新id=2的数据,name改为‘李四’,发现居然成功了?此时我们再查询id为2的数据,发现查询出来了,并且name已经改为李四。

可见,幻读就是没有读到的记录,以为不存在,但其实是可以更新成功的,并且,更新成功后,再次读取,就出现了

四、序列化读(Serializable)

  • 最严格的隔离级别。在Serializable隔离级别下,所有事务按照次序依次执行,因此,脏读、不可重复读、幻读都不会出现

    虽然Serializable隔离级别下的事务具有最高的安全性,但是,由于事务是串行执行,所以效率大大下降,应用程序的性能会急剧降低。如果没有特别重要的情景,一般都不会使用Serializable隔离级别。

  • 默认隔离级别

    如果没有指定隔离级别,数据库就会使用默认的隔离级别。在mysql中,如果使用InnoDB默认的隔离级别是Repeatable Read。Oracle默认的隔离级别是read Committed。

  • 另外补充事务的四种级别:原子性、一致性、隔离性、持久性。

事务的四种隔离级别

1,读未提交,Read Uncommited。

指的是一个事务读取到另外一个事务还没有提交的内容。这种情况是必须要避免的。因为其他事务未提交的数据,是随时有可能进行回滚的,所以,任何时候,都不应该允许程序读取到某个事务还未提交的数据。如果读取到了别的事务未提交的数据,这种情况称为脏读。要想解决脏读的问题,可以提高数据库的事务隔离级别,把事务隔离级别设置为读已提交。

2,读已提交,Read Committed。

这个隔离级别可以解决脏读的问题。

在该隔离级别下,不允许2个未提交的事务之间并行执行,但它允许在一个事务执行的过程中,另外一个事务得到执行并提交。这样,会出现一种情况,第一个事务前后两次select出来的某行数据,值可能不一样。值改变的原因是,穿插执行的事务2对该行数据进行了update操作。在同一个事务中,两次select出来的值不相同的问题称为不可重复读问题。要想解决不可重复读问题,需要把数据的隔离级别设置为可重复读。

3,可重复读。Repeatable Read。

在这个隔离级别下,可以解决不可重复读的问题。

在该隔离级别下,在一个事务使用某行的数据的过程中,不允许别的事务再对该行数据进行操作。可重复读应该是给数据库的行加上了锁。这种隔离级别下,依旧允许别的事务在该表中插入和删除数据,于是就会出现,在事务1执行的过程中,如果先后两次select出符合某个条件的行,如果在这两次select直接另一个事务得到了执行,insert或delete了某些行,就会出现先后两次select出来的符合同一个条件的结果不一样,第一次select好像出现了幻觉一样,因此,这个问题也被成为幻读。要想解决幻读问题,需要将数据库的隔离级别设置为串行化。

4, 串行化,Serialization。

串行化可以解决幻读的问题。

它要求事务的执行完全串行执行。所以失去了并发的效率。

Mysql的默认隔离级别为可重复读。

总结而言,数据的事务隔离级别分为4种,从低到高依次为读未提交,读已提交,可重复读,串行化。与数据库事务隔离级别相关的问题有3个,分别是脏读,不可重复读,幻读。脏读问题需要用读已提交来解决,但读已提交会存在不可重复读问题。不可重复读问题需要用可重复读来解决,但可重复读会存在幻读问题。幻读问题需要用串行化来解决。
————————————————
版权声明:本文为CSDN博主「bugcoder321」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/li_canhui/article/details/83058068

以上是关于事务的四种隔离级别(超详细!!!)的主要内容,如果未能解决你的问题,请参考以下文章

事务的四种隔离级别

事务的四种隔离级别

MySQL数据库中的四种隔离级别

MySQL 事务的四种隔离级别

数据库事务的四种隔离级别

数据库事务的四种隔离级别