您现在的位置是:主页 > news > 国外还有那种做电商的网站/分销系统
国外还有那种做电商的网站/分销系统
admin2025/5/4 21:43:24【news】
简介国外还有那种做电商的网站,分销系统,长沙网站设计,新疆网站设计前言最近在准备春招的过程中顺手复习了一下MySQL的事务隔离级别,现在整理出来和各位同学一起学习,若有不对的地方请指教。在这之前先看看相关的面试题:MySQL有哪些事务隔离级别?Read Commit(读已提交)级别是如何解决脏读的&#x…
前言
最近在准备春招的过程中顺手复习了一下MySQL的事务隔离级别,现在整理出来和各位同学一起学习,若有不对的地方请指教。
在这之前先看看相关的面试题:
MySQL有哪些事务隔离级别?
Read Commit(读已提交)级别是如何解决脏读的?
Repeatable Read(可重复读)级别是如何解决不可重复读的?
MySQL是如何解决幻读的?MVCC可以解决幻读问题吗?
相关概念
首先先介绍一下脏读、不可重复读和幻读:
脏读:指一个事务可以看到另一个事务未提交的数据。
比如说事务A修改了一个值但是还未提交,这时事务B可以看到A修改的值,这就是脏读。
不可重复读:一个事务执行两次同样的查询语句,前后得出的数据却不一致。
比如说事务A执行了select语句,事务B修改了某个值,事务A再次执行select语句时发现结果和上次不一致,因此叫做不可重复读。
幻读:在同一个事务中,同一个查询多次返回的记录行数不一致(这里的结果特指查询到的记录行数,幻读可以看做不可重复读的一种特殊情况)。
比如说事务A执行了select语句,事务B插入数据,事务A再次执行select语句时发现多了几条记录,好像出现了幻觉一样,因此叫做幻读。
MySQL有哪些事务隔离级别?
级别从低到高分别是:未提交读、已提交读、可重复读、串行化
下图是各个隔离级别以及可能会出现的问题:
Read Commit(读已提交)级别是如何解决脏读的?
先说结论:通过改变锁的释放时机来解决脏读问题。
首先先了解一下为什么会出现脏读?原因就是在未提交读这个级别下,当事务A修改了数据之后就立马释放了锁,因此事务B可以读取到这个未提交的数据。
在已提交读级别下写操作加的锁会到事务提交后释放,所以事务B不会读到事务A未提交的数据,通过改变锁的释放时机解决了脏读的问题。
Repeatable Read(可重复读)级别是如何解决不可重复读的?
结论:可重复读级别就是通过MVCC机制来解决不可重复读问题的
MVCC机制(多版本并发控制)就我个人理解来说其实就是给每行数据都添加了几个隐藏字段,用来表示数据的版本号,即一个数据在mysql中会有多个不同的版本,想深入了解MVCC请参考:MVCC机制
MVCC就是给每一行都都有个事务版本号,假设一条链表第一个节点是最新的数据,越后数据越旧,当有一个快照读操作过来后,会遍历链表,找到第一个当前事务可见的数据。
有了MVCC之后我们可以把SQL操作分为两类:
快照读
读取当前事务可见的数据,默认的select操作就是快照读,读的是历史版本的数据。
当前读
读取最新的数据,除了默认select操作外的select..for update、update、insert、delete等操作都是当前读,读取的都是最新的数据。
现在我们有了MVCC,当事务A执行一个普通的select操作(快照读),MySQL会把这次读取的数据保存起来,在这期间不管事务B执行update或是insert操作,事务A再次执行select操作读取到的数据是不会变的,因此通过可重复读级别通过MVCC解决了不可重复读问题,顺便解决了部分的幻读问题,没错MVCC并没有解决所有的幻读问题,只是解决了一部分,那是如何彻底解决幻读问题的呢?请接着往后看。
MySQL是如何解决幻读的?MVCC可以解决幻读问题吗?
先说结论:MVCC并不能解决所有的幻读问题,MySQL是通过MVCC + Next Key Lock来解决幻读问题的。
为什么MVCC不能解决幻读?
因为当事务执行的是加锁的select操作(当前读),每次执行都是读取最新的数据,事务A是可以看到事务B修改的数据的,那么还是会出现幻读的问题,因此MySQL引入了一种叫做Next Key Lock的算法,简单来说就是对一个范围加锁,这样子当事务A执行select..for update时会对数据加锁,这时事务B是无法执行update、insert等操作的,因此MySQL是通过MVCC + Next Key Lock来解决幻读问题的,有关Next Key Lock请参考Innodb锁机制:Next-Key Lock 浅谈
总结
有关MySQL隔离级别就讲到这里啦,这些都是本人的一些心得,如果有什么不对的地方请各位大佬们多多指教!