懂的越多,不懂的越多
有时候,我们会陷入一些思维误区,尤其是并发情况,最经典的一个例子就是,一些前后端分离的项目,总是会有这样的需求 “前端的处理数据效果比较差,在后端把数据处理好了返回给前端展示就好”,忘了最重要的一个问题,后端只有一个,前端有多少用户就有多少处理器。
上边的话题只是吐槽以下,和今天的主题关系不大,我们经常在面试的时候碰到询问mysql的事务隔离级别。
面试管:你说下Mysql的事务隔离级别
答:Mysql事务的隔离级别分为四种,分别为未提交读,已提交读,可重复读,串行化。
未提交读:会导致脏读(读到的数据与预期数据不一致)问题
已提交读:解决了脏读问题,但是会出现不可重复读问题(同一事务重复读取同一条数据,得到的结果不同)
可重复读:解决了之前的问题,Mysql的InnDB引擎使用的就是这一隔离级别,会出现幻读问题(事务中查询年龄大于50的人,同一事务中两次查询,中间别的事务有插入一条年龄大于50的人的数据,那么就会出现第二次和第一次查询的数据量的不同)
可串行化:每次读取都会加上锁,会导致大量的超时现象
这里有个东西要重点说下:
多个事务同时读数据,在任何隔离级别都是可以执行的 (读锁是共享锁)
多个事务同时写数据,在任何隔离级别都是不可执行的 (写锁是互斥锁)
以上的隔离级别都是为了解决多个事务有读有写的情况的
幻读和不可重复读区别:update和delete属于不可重复读,insert属于幻读,也就是修改数据和删除数据属于不可重复读,只有新增数据属于幻读
面试管:为什么update和delete属于不可重复读,insert属于幻读?
我的内心毫无波动甚至想睡个觉,程序员的事,哪来的那么多为什么?
答:可重复读在读取记录时,会使用行级锁,将读取的记录加上锁,这时数据就不可修改和删除了,但是新增数据,并不会被限制,所以update和delete属于不可重复读,insert属于幻读
面试管:你刚刚有提到Mysql使用的是可重复读的隔离级别,那么就是说现在的Mysql数据会出现幻读的问题了?
凉凉夜色为你成河,为啥我要显摆下自己知道Mysql的默认隔离级别
答:当然不会,Mysql使用间隙锁方案,解决了当前读下的幻读问题,就比如刚刚查询年龄大于50的人的数据,间隙锁会锁住年龄等于50和大于50之后的区间,这样就无法在这个范围插入数据,就保证了不会出现幻读问题。使用了MVCC来解决快照读的重复读的问题,在InnDB引擎下,使用版本链+ReadView来实现MVCC。