闲着无事,想写一篇完整的关于mysql事务知识点,不会很深入,但是把mysql事务知识完整的串起来了,之前学习没找到一篇完整的,总是发现新的不知道,这篇应该还有更新,目前事务我了解到的知识点已经完整的串起来了。
首先,事务不用介绍了吧,事务的几个特性,大家应该都清楚。但是事务的隔离性,在并发时会产生几个问题可能都知道一点,就是脏读、不可重复读、幻读,注意是并发的情况会产生这三个问题,
脏读:就是别人还没走完事务,只是要修改,你就读取了,万一它反悔了呢,不想修改了。你读取的不就是错误数据
不可重复读:在一次事务当中,每次读取同一条数据,读取的总是不同。这是为啥?是因为别人总在改数据,你就读取的不同了。
幻读:第一次查询数据有3条,第二次查询就5条了,这是幻觉吗?这别人插入了一条数据。这就是幻读,
因此呢,针对上述情况,数据库就产生了隔离等级。隔离等级有四个,由低到高分别为Read uncommitted 、Read committed 、Repeatable read 、Serializable 。这个四个等级分别解决什么问题,大家可以网上找一篇看看。
了解这四个隔离等级后,我说下常见数据库使用的那个等级,一般大多数使用的Read committed比如:orcal、sql sever等。
而我们mysql却用的repeatable read,似乎是因为主从复制的有bug所以改成用这个等级了。这个等级一般情况下是用for update来解决隔离性问题。但是这样会降低性能,尤其是一些情况下会从锁行变成锁表,所以mysql的大佬们就不乐意了,我这性能变低了啊。于是mysql的mvcc(多并发版本控制)机制诞生了,它解决了读的同时还可以写,详细原理,门:mvcc详解
看完这个可能还有点懵,再次传送门mvcc快照读、当前读举例子说明 再看完这个博客,应该就明白了快照读吧,也明白了mysql是如何解决可重复的读,白话讲就是读取时生成ReadView,所以在这次事务中,每次读取都是一样的数据,这样就解决了不可重复读了。
按我理解mysql这个解决方法,没有解决当我读取后,别人不能修改这个数据的问题。也就是以下场景:小李在商城付款买个ps5,与此同时小李老婆买了个包,蹩脚开发代码这样写的先查询卡上余额够不够,如果够算出新的余额,再更新余额。原本包和ps5一起的钱,小李的余额是不够的,但是因为查询时没有锁住,造成了两个都买了,最后余额变成了买完包的钱。
所以我们在使用mysql时,多次读取要保证数据一致,还是需要使用锁的。
我就是这样阅读的顺序,明白了mysql的re peatable read是怎样的。
请大家多多指教,时不时更上班遇到的问题