数据库-并发产生的问题
锁模块之事务并发访问产生的问题
我们先来看下数据库的默认隔离级别:
我们知道MySQL数据库有四种事务隔离级别,除了serializable是绝对安全,其他的隔离级别都在某些情况下存在不安全的情况。不安全的情况包括:脏读、不可重复读、幻读。脏读在读已提交事务隔离级别就可以被解决;不可重复读可以被可重复读事务隔离级别解决,幻读可以被串行化事务隔离级别解决。
脏读:
读到一个被另一个会话回滚的数据
-
先将两个会话的事务隔离级别改为读未提交:
-
开启事务模拟脏读问题场景:
-
B会话把原先数据库该条数据的金额修改为900,然后A会话这时去读取这条数据,并且我采用这条数据去处理业务,但是B会话后悔了,它回滚了,这下完了,A会话拿着一个脏数据去处理了业务,那这样会造成很大的问题。
-
将事务隔离级别上调一个级别:读已提交,脏读的场景就会被解决
看图就会发现,A会话只能读到已经提交的数据,避免了脏读的发生
不可重复读
前后读取的数据不一致,前后不一。不可重复读侧重于一条数据的内容前后读取不一致
我们再将事务隔离级别上调一级
不可重复的就被解决
幻读
幻读与不可重复读的区别在于,幻读是指前后读取的数据条数不一样,导致像出现幻觉一样
我们用插入一条数据来还原现场
哦哟,看到这个是不是有点想翻车的样子,并没有产生幻读呀,其实,在现实情况下,可重复读事务隔离级别已经帮我们解决好了,所以不会出现这个问题。所以我们将事务隔离级别下调至RC级别,再来看看。
看看A会话,我们明明只有三条数据,但在更新时却显示更新了4条数据,这就是幻读,解决就是将事务隔离级别上调至串行化,即可解决
###总结
事务隔离级别\并发问题 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | 出现 | 出现 | 出现 |
读已提交 | 不出现 | 出现 | 出现 |
可重复读 | 不出现 | 不出现 | 出现(理论) |
串行化 | 不出现 | 不出现 | 不出现 |
事务隔离级别,级别越高,安全性越高,但是随之而来的问题也就是性能越低。