网上看了很多的解读,都只回答了概念的问题,再加上脏读、幻读等概念的混淆,很多人都一头雾水,没有真正地理解,所以还是要演示一下以便更好地理解和记忆。
一、首先演示第一个级别,也是安全系数最低的级别,就是读未提交(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。
-
另外补充事务的四种级别:原子性、一致性、隔离性、持久性。