【面经】MYSQL的锁、可重复读是怎么实现的、线程池

1、MySQL的锁

参考:https://blog.csdn.net/qq_40378034/article/details/90904573

全局锁

给整个数据库实例加锁。例如全局读锁:Flush tables with read lock。

应用场景:全库逻辑备份,将整个库的每个表都select出来存成文本。

表级锁

两种:表锁、元数据锁。

表锁:lock tables…read/write。

MDL(元数据)锁:当对一个表做增删改查操作的时候,加MDL读锁;当要对表结构做变更操作的时候,加MDL写锁。

事务的MDL锁在语句执行开始时申请,但是语句结束后并不会马上释放,而会等到整个事务提交后释放。

行锁

不是所有引擎都支持行锁,MyISAM不支持。

在InnoDB中,行锁是在需要的时候加上的,但是要等到事务结束时才释放。(两阶段锁协议)

把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。

当出现死锁时,有两种策略:

  • 设置超时时间。直接进入等待,直到超时。
  • 发起死锁检测,回滚死锁链中的某个事务。

开启死锁检测后,每当一个事务被锁的时候,就要看看他所依赖的线程有没有被别人锁住,如此循环,最后判断是否出现了循环等待(死锁)。如果所有事务都要更新同一行,那么每个新来的阻塞线程都要判断会不会由于自己的加入导致死锁。
这种性能问题如何解决?

  • 1、暂时将死锁检测关掉;
  • 2、控制并发度;
  • 3、将一行改成逻辑上的多行来减少锁冲突。

间隙锁

为了解决幻读问题,InnoDB引入了间隙锁,锁的是两个值之间的空隙。
在这里插入图片描述
当执行select * from t where d=5 for update的时候,就不止是给数据库中已有的6个记录加上了行锁,还同时加了7个间隙锁。这样就确保了无法再插入新的记录。

间隙锁+行锁合称为next-key lock,每个next-key lock是前开后闭区间。

2、可重复读是怎么实现的?

通过MVCC解决的。

InnoDB中每个事务都有一个唯一的事务ID,是在事务开始的时候向InnoDB的事务系统申请的,按照申请顺序严格递增的。
在每条记录进行更新的时候都会同时记录一条undo log链,这条log会记录上当前事务的事务id( row trx_id ),记录的最新状态通过回滚可以得到前一个状态的值。

在这里插入图片描述在这里插入图片描述

3、线程池

可以聊的点:线程池的好处、实现原理、七大参数、四大拒绝策略。

四大拒绝策略:

  • ① AbortPolicy(直接抛出异常)
  • ② CallerRunsPolicy:只用调用者所在线程来运行任务
  • ③ DiscardOldestPolicy:丢弃队列里最近的任务,并执行该任务
  • ④ DiscardPolicy:不处理,直接丢弃

线程池的执行流程

类比成坐公交:首先上车,看靠窗的位置(核心线程池)是否坐满,坐满了则看其他位置(等待队列)是否坐满,坐满了则看公交还有没有站的位置(整个线程池是否还有空位),要是整个公交都满了就只能看司机怎么安排了(拒绝策略处理)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值