数据库-并发产生的问题

锁模块之事务并发访问产生的问题

我们先来看下数据库的默认隔离级别:

数据库-并发产生的问题

我们知道MySQL数据库有四种事务隔离级别,除了serializable是绝对安全,其他的隔离级别都在某些情况下存在不安全的情况。不安全的情况包括:脏读、不可重复读、幻读。脏读在读已提交事务隔离级别就可以被解决;不可重复读可以被可重复读事务隔离级别解决,幻读可以被串行化事务隔离级别解决。

脏读:

读到一个被另一个会话回滚的数据

  • 先将两个会话的事务隔离级别改为读未提交:

    数据库-并发产生的问题

  • 开启事务模拟脏读问题场景:

    数据库-并发产生的问题

  • B会话把原先数据库该条数据的金额修改为900,然后A会话这时去读取这条数据,并且我采用这条数据去处理业务,但是B会话后悔了,它回滚了,这下完了,A会话拿着一个脏数据去处理了业务,那这样会造成很大的问题。

  • 将事务隔离级别上调一个级别:读已提交,脏读的场景就会被解决

    数据库-并发产生的问题

    看图就会发现,A会话只能读到已经提交的数据,避免了脏读的发生

不可重复读

前后读取的数据不一致,前后不一。不可重复读侧重于一条数据的内容前后读取不一致

数据库-并发产生的问题

我们再将事务隔离级别上调一级

数据库-并发产生的问题

不可重复的就被解决

幻读

幻读与不可重复读的区别在于,幻读是指前后读取的数据条数不一样,导致像出现幻觉一样

我们用插入一条数据来还原现场

数据库-并发产生的问题

哦哟,看到这个是不是有点想翻车的样子,并没有产生幻读呀,其实,在现实情况下,可重复读事务隔离级别已经帮我们解决好了,所以不会出现这个问题。所以我们将事务隔离级别下调至RC级别,再来看看。

数据库-并发产生的问题

看看A会话,我们明明只有三条数据,但在更新时却显示更新了4条数据,这就是幻读,解决就是将事务隔离级别上调至串行化,即可解决

###总结

事务隔离级别\并发问题 脏读 不可重复读 幻读
读未提交 出现 出现 出现
读已提交 不出现 出现 出现
可重复读 不出现 不出现 出现(理论)
串行化 不出现 不出现 不出现

事务隔离级别,级别越高,安全性越高,但是随之而来的问题也就是性能越低。