事务的丢失更新
我们都知道,Mysql Innodb引擎的默认事务隔离级别是RR可重复读,也就是在同一个事务中,多次读取相同的数据结果相同。而其底层就是通过:“排它锁+MVCC”来实现的。 话不多说,我们来看看下面的这个问题: 我们可以看到,上面的事务A在更新数据之前,数据已经被事务B所修改,但是事务A最终提交的时候,将事务B的提交覆盖掉了,导致了事务B的更新丢失。 用我们之前学过的MVCC来理解一下为什么这个问题会发生: 首先由于事务A开启的时候,事务B还没提交,此时A事务进行了一次select操作,导致生成ReadView。根据这张图的原理: B事务处于trx_ids的事务中,所以A事务无法看到B事务的数据处理过程,即B事务对数据的操作,对A事务不可见。这也正是可重复读的实现的原理。 而恰恰是因为A事务看不到B事务对数据的更新,而A事务本地无论如何都是读到该数据的1000元可重复读的版本,导致A事务后面的更新操作直接在1000元这个版本上对数据添加100,将B事务的更新完全覆盖。 那么如何解决上面的这个问题呢? 我们来看看上面问题的本质,其实就是在事务B操作数据之前,我们就调用了select,导致生成了ReadView,而我们又拿着这个select的数据去做后面的处理,最终导致了B数据的丢失。 看到这里可能有人会想