***搜集到的一些有用的Mysql经典《八股文》,全篇手打,大家觉得有用的话点一个赞,持续更新
目录
1.Mysql锁的机制:
粒度分类:
思想分类:
实现分类:
状态分类:
1.Mysql锁的机制:
如上图所示我们将锁分为了五大部分进行理解,如果按照网上大多数博主那样上来一直说大白话显得很难读懂,索性我们按照分类来进行记忆,这样会显得更加清晰明了。
粒度分类:
全局锁:
定义:全局锁是对整个数据库实例加锁,它可以确保整个数据库处于只读状态,防止并发的写操作。
为什么要存在全局锁?
场景:当前我们需要对整个数据库表进行导出(假设当前以银行为背景,并且没有加全局锁),在我们导出sql文件的一瞬间,有人进行了消费,转账改变了原表数据(原用户表金额属性发生了变化),那么请问当前导出的sql文件是改呢?还是不改呢?
应用:
所以我们加上了全局锁就可以防止在导出表,或者恢复表的时候其他DDL语句对数据进行改变。
表级锁:
定义:表级锁是对数据表加锁,可以是读锁(共享锁)或写锁(排他锁)的形式。读锁之间不互斥,多个事务可以同时持有读锁;(在MYISAM中读操作,会自动加上读锁,写操作自动加上写锁,因为这个引擎不支持事务,所有他会加强行锁来保证稳定性,而在InnoDB中必要情况下会用表锁,大多情况用的是行锁,这个后面会解释)
为什么要存在表级锁?
在大多情况下用不着将全局整个数据库进行加锁,我们可能只需要对某个经常读写的表进行加锁即可,那么我们就会选择粒度小一点的表级锁。
应用:
1.读密集型应用(读多写少的时候)
2.数据量比较小
3.全表更新或删除
缺点:
1.降低性能(因为锁了整个表,当并发量高的时候会很慢,因为大家都在等)
2.锁超时(当一些操作长时间无法进行提交的时候)
3.死锁(两线程互相锁)
行级锁
定义:行级锁是对某行数据加锁,其他事务可以访问表中其他行而不被阻塞。行级锁可以是共享锁或排他锁,类似于读锁和写锁的概念,但是行级锁是针对单行数据的。(粒度最小,死锁发生概率最大,CPU和资源耗费最多的一个锁)
为什么要存在行级锁?
适用于高并发环境下对数据库中特定行进行读写操作,可以提高并发性能。
应用:
1.高并发读写
2.单行操作
3.insert.update.delete,这些操作都会有行锁(排他锁)
缺点:
1.锁冲突(会比上面行锁小一点)
2.死锁
3.内存消耗(cpu和资源是最大的,因为粒度最细)
思想分类:
所谓的乐观锁和悲观锁不过是一种思想。
乐观锁
定义:主打一个乐观,认为不会发生冲突,所以任何时候都不加锁,当多操作同时对一个数据进行修改的时候,能否成功修改在于修改时的version和修改前的version是否相同来保证,如果相同则进行修改并让version进行加一,如果不同则进行回滚重新等下一次操作机会(数据库里面没有乐观锁的具体实现,我们一般用版本号version进行判断,初始值为零,每次修改成功进行加一,version也是我们建立用户表或者商品表的一个重要字段)
优点:
当并发量小的时候速度很快,因为我们任何时候都没有加锁,所以执行速度就会比较快
缺点:
相对于优点来说,如果并发量大的时候,同一时间涌进来了大量数据,但是一瞬间只有一个操作可以进行实现,其他的都需要等待,这个时间就会非常长。
应用:
比如说用户表,对于用户表来说大多时间我们都是一种读的形式,很少改,所以我们可以采用建立用户表的时候加入一个version字段进行乐观锁的表示。
悲观锁(并发机制)
定义:主打一个悲观,认为任何时候都会发生冲突,所以任何时候都会进行加锁,当多操作对同一数据修改的时候,可以保证数据的安全性和可靠性(mysql有实现方式,共享锁和排他锁都可以)
优点:
1.数据安全性(串行化)
2.实现简单
缺点:
1.在并发情况下,大家会直接等,然后一个一个来
2.锁冲突和死锁风险高
应用:
强一致性的时候,这个是优于乐观锁的,因为乐观锁说白了是用回滚,而悲观锁是直接强行锁住一个一个来。
实现分类:
共享锁(S锁/读锁),排他锁(X锁/写锁)--------这两个锁也是我们用的最多的两个锁
共享锁
定义:阻止用户进行更新修改数据,只允许读取数据。
特点:
共享锁允许多个事务同时持有锁,用于读操作。共享锁之间不会互斥,多个事务可以同时读取同一数据,不会互相干扰。
优点:
共享锁适用于并发度较高的读操作场景,可以提高并发性能。
缺点:
在持有共享锁的情况下,其他事务无法获取排他锁,从而阻塞了写操作的执行。
应用:
共享锁常被用于多个事务并发读取数据的情况,例如读取数据的查询操作。多个事务可以共享对数据的读取权限,不会相互冲突。
排他锁
定义:阻止用户进行读取数据,只允许修改操作数据。
特点:
排他锁只允许独占访问,用于写操作。在一个事务持有排他锁期间,其他事务无法获取共享锁或排他锁,从而确保数据的独占性。
优点:
排他锁适用于独占式的写操作,保证了数据的一致性和完整性。
缺点:
在持有排他锁的情况下,其他事务无法读取或修改数据,从而对并发性能产生影响。
应用:
排他锁常被用于修改数据的操作,例如插入、更新或删除操作。事务持有排他锁时,其他事务无法同时进行写操作,防止数据的并发冲突。
状态分类:
其实主要就是在实现(排他锁和共享锁)上加了一个意向锁,它是一个表锁,为了协调行锁和表锁的关系,支持多粒度(行锁和表锁)共存。
作用:当事务A已经存在行锁的时候,mysql会自动为其增加一个意向锁,事务B如果想申请表级写锁,那么就不需要在遍历每一行是否有行锁(因为表级写锁和行级写锁不共存),直接判断是否存在意向锁即可,大大提高了时间效率(如果没有意向锁,那么就会循环遍历,浪费shi'j)