当面试官问到:《MySQL数据库的锁机制》该如何拿分?

124面试必问:谈谈微服务的数据库设计思路 单独的数据库 微服务设计的一个关键是数据库设计,基本原则是每个服务都有自己单独的数据库,而且只有微服务本身可以访问这个数据库。它是基于下面三个原因。 优化服务接口:微服务之间的接口越小越好,最好只有服务调用接口(RPC或消息),没有其他接口。如果微服务不能独享自己的数据库,那么数据库也变成了接口的一部分,这大大拓展了接口范围。 错误诊断:生产环境中的错误大部分都是和数据库有关的,要么是数据出了问题,要么是数据库的使用方式出了问题。当你不能完全控制数据库的访问时,会有各种各样的错误... 阅读详情

为什么要加锁?

问题背景

  • 当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

要解决的问题

  • 多用户环境下保证数据库完整性和一致性

锁是什么

  • 在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足。
  • 加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。

锁的分类

行

  • 行级锁
  • 行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁 和 排他锁。
  • 特点
  • 开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

表

  • 表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持。最常使用的MYISAM与INNODB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)。
  • 特点
  • 开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低。

页

  • 页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。BDB支持页级锁
  • 特点
  • 开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

MySQL常用存储引擎的锁机制

MyISAM和MEMORY采用表级锁(table-level locking)

BDB采用页面锁(page-level locking)或表级锁,默认为页面锁

InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁

  • InnoDB行锁是通过给索引上的索引项加锁来实现的,InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!

在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能。

行级锁都是基于索引的,如果一条SQL语句用不到索引是不会使用行级锁的,会使用表级锁。行级锁的缺点是:由于需要请求大量的锁资源,所以速度慢,内存消耗大。

实例说明

  • MySQL InnoDB引擎默认的修改数据语句:update,delete,insert都会自动给涉及到的数据加上排他锁。

select语句默认不会加任何锁类型,如果加排他锁可以使用select …for update语句,加共享锁可以使用select … lock in share mode语句。

所以加过排他锁的数据行在其他事务种是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select …from…查询数据,因为普通查询没有任何锁机制。

行级锁与死锁

MyISAM中是不会产生死锁的,因为MyISAM总是一次性获得所需的全部锁,要么全部满足,要么全部等待。而在InnoDB中,锁是逐步获得的,就造成了死锁的可能。

在MySQL中,行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql语句操作了主键索引,MySQL就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。在UPDATE、DELETE操作时,MySQL不仅锁定WHERE条件扫描过的所有索引记录,而且会锁定相邻的键值,即所谓的next-key locking。

当两个事务同时执行,一个锁住了主键索引,在等待其他相关索引。另一个锁定了非主键索引,在等待主键索引。这样就会发生死锁。

发生死锁后,InnoDB一般都可以检测到,并使一个事务释放锁回退,另一个获取锁完成事务。

共享锁与排它锁

共享锁(Share Lock)

  • 共享锁又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。

如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。

用法 SELECT ... LOCK IN SHARE MODE;

在查询语句后面增加LOCK IN SHARE MODE,Mysql会对查询结果中的每行都加共享锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请共享锁,否则会被阻塞。其他线程也可以读取使用了共享锁的表,而且这些线程读取的是同一个版本的数据。

排它锁(eXclusive Lock)

  • 排他锁又称写锁,如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。

用法 SELECT ... FOR UPDATE;

在查询语句后面增加FOR UPDATE,Mysql会对查询结果中的每行都加排他锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请排他锁,否则会被阻塞。

乐观锁(Optimistic Lock)

是什么

  • 假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。

相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本。

数据版本,为数据增加的一个版本标识。当读取数据时,将版本标识的值一同读出,数据每更新一次,同时对版本标识进行更新。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的版本标识进行比对,如果数据库表当前版本号与第一次取出来的版本标识值相等,则予以更新,否则认为是过期数据。

实现数据版本有两种方式,第一种是使用版本号,第二种是使用时间戳。

使用版本号实现乐观锁

  • 使用版本号时,可以在数据初始化时指定一个版本号,每次对数据的更新操作都对版本号执行+1操作。并判断当前版本号是不是该数据的最新的版本号。
1.查询出商品信息
select (status,status,version) from t_goods where id=#{id}
2.根据商品信息生成订单
3.修改商品status为2
update t_goods
set status=2,version=version+1
where id=#{id} and version=#{version};

优点与不足

  • 乐观并发控制相信事务之间的数据竞争(data race)的概率是比较小的,因此尽可能做下去,直到提交的时候才去锁定,所以不会产生任何锁和死锁。但如果直接简单这么做,还是有可能会遇到不可预期的结果,例如两个事务都读取了数据库的某一行,经过修改以后写回数据库,这时就遇到了问题

悲观锁(Pessimistic Lock)

是什么

  • 在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制 (也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)

悲观锁的流程

  • 在对任意记录进行修改前,先尝试为该记录加上排他锁(exclusive locking)。
  • 如果加锁失败,说明该记录正在被修改,那么当前查询可能要等待或者抛出异常。具体响应方式由开发者根据实际需要决定。
  • 如果成功加锁,那么就可以对记录做修改,事务完成后就会解锁了。
  • 其间如果有其他对该记录做修改或加排他锁的操作,都会等待我们解锁或直接抛出异常。

MySQL InnoDB中使用悲观锁

  • 要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。set autocommit=0;
//0.开始事务
begin;
//1.查询出商品信息
select status from t_goods where id=1 for update;
//2.根据商品信息生成订单
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status为2
update t_goods set status=2;
//4.提交事务
commit;

上面的查询语句中,我们使用了select…for update的方式,这样就通过开启排他锁的方式实现了悲观锁。此时在t_goods表中,id为1的 那条数据就被我们锁定了,其它的事务必须等本次事务提交之后才能执行。这样我们可以保证当前的数据不会被其它事务修改。

Java的锁机制

线程的同步问题

  • 一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在java里边就是拿到某个同步对象的锁(一个对象只有一把锁);如果这个时候同步对象的锁被其他线程拿走了,他(这个线程)就只能等了(线程阻塞在锁池等待队列中)。取到锁后,他就开始执行同步代码(被synchronized修饰的代码);线程执行完同步代码后马上就把锁还给同步对象,其他在锁池中等待的某个线程就可以拿到锁执行同步代码了。这样就保证了同步代码在统一时刻只有一个线程在执行。

线程的同步方法:

  • 1. 在需要同步的方法的方法签名中加入synchronized关键字。
  • 2. 使用synchronized块对需要进行同步的代码段进行同步。
  • 3. 使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象。

ThreadLocal

当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。在ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本。使用ThreadLocal的典型场景如数据库连接管理,线程会话管理等场景,只适用于独立变量副本的情况,如果变量为全局共享的,则不适用在高并发下使用。

获取资料:

最后给大家分享一些学习资料,里面包括:(BATJ面试资料、高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)和Java进阶学习路线图。

免费领取方式:点击此处【链接】 即可免费。

资料整理不易,请转发评论,最后,祝大家早日学有所成!

面试官:通过Mysql查询的时候,为什么有时候即使查询一条数据也很慢呢? 导致查询慢的几个方面的原因,一是 MySQL 数据库偶发性地需要flush数据,此时因为redo log空间的问题或者是buffer pool空间的问题导致数据库阻塞,进而导致数据库查询偶发性地变慢。二是锁机制导致的问题,如果上一个事务增加了排他锁而其他事务同时也加上了锁,那么就会导致阻塞,此时也会导致数据查询变慢。可能是死锁了,然后又释放了!三是索引不合理或条件不合理。 阅读详情

相关推荐

Ollama部署本地大模型详细教程

创建ModelfilePARAMETER num_gpu 50 # GPU 层卸载比例(0~100)场景是否推荐本地开发/测试 Agent✅ 强烈推荐内部知识库问答(RAG)✅ 推荐(配合 Pgvector)生产环境高并发服务⚠️ 谨慎(建议评估 vLLM / Triton)需要 Function Calling 的 Agent❌ 不推荐(改用 DashScope API)🔑核心价值Ollama 是“本地大模型的 Docker”——让开源模型像容器一样 easy to run。

我们的征途是星辰大海 2621

mysql五四机制_当面试官问到:《MySQL数据库的锁机制》该如何拿分?

为什么要加锁?问题背景当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。要解决的问题多用户环境下保证数据库完整性和一致性锁是什么在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足。加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对...

weixin_29901323的博客 93

我看MFC的过去、现在和未来

首先说句题外话,虽然我现在的“主业”是Qt,但自己扪心自问,对MFC的熟悉程度要超过Qt。正是由于有了对MFC的熟悉,才能在使用Qt时,比较清醒的认清两者的优劣之处,在此暂且不提。 这个话题也可以说是由来已久,众说纷纭,今时我也谈谈自己的感悟。 一、对MFC的总体看法 首先看看云风在其《游戏之旅-我的编程感悟》一书中对MFC的看法: “我所见到的程序员中,很多把C+

qter_wd007的专栏 6115

mysql 加锁 索引_当面试官问到:《MySQL数据库的锁机制》该如何拿分?

为什么要加锁?问题背景当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。要解决的问题多用户环境下保证数据库完整性和一致性锁是什么在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足。加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对...

weixin_42509396的博客 74

四大厂商网络设备巡检命令实战指南:华为、华三、锐捷、思科

本文详细介绍了华为、华三、锐捷、思科四大厂商网络设备的巡检命令实战指南,涵盖硬件状态、软件运行和网络功能等核心维度。通过具体命令示例和实用技巧,帮助网络工程师高效完成设备巡检,预防潜在故障,确保网络稳定运行。

weixin_29235923的博客 391

车道线检测(传统基于Opencv的方法)

传统车道线检测方法主要是使用颜色选择、高斯平滑、边缘检测、ROI区域选择、霍夫变换、标定车道边界等Opnecv图像处理操作去检测道路上的车道线,我自己对很多用这类处理对很多道路场景车道线进行过实验,这类算法往往需要人工根据不同街道场景手动去反复调整各算法参数,从而才能使检测效果最佳。

Yangxiaoaijiejie的博客 2072

面试让HR都能听懂的MySQL锁机制,欢声笑语中搞懂MySQL锁

腾讯云数据库负责人林晓斌说过:“我们面试MySQL同事时只考察两点,索引和锁”。言简意赅,MySQL锁的重要性不言而喻。 本文通过同事“侨总”的一场面试,带你通俗易懂的掌握MySQL各种锁机制,希望可以帮到你!

陈哈哈的菜园子 2万+

目标跟踪与视频时序分析基础

两帧均有目标,却因快速移动导致检测框无重叠,仅靠交并比(IoU)无法维持身份关联。本文通过手算与纯Python实现最小跟踪流程,揭示IoU仅为位置线索,不能应对快速位移或遮挡。实验表明,即使目标真实存在,低重叠也会触发新编号。强调跟踪需结合运动预测、外观特征与阈值验证,避免误判。

Mr数据杨 2335

面试官问:请介绍一下MySQL数据库的锁机制?

为什么要加锁 问题背景 当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。 要解决的问题 多用户环境下保证数据库完整性和一致性 锁是什么 在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足。 加锁是实现数据库并发控制的一个非常重要的...

209

Codex入门10-Goal自主任务(进阶必学:设定目标就不管了,AI自己干活到完成)

/goal 是Codex CLI最强大的进阶功能——设定一个目标,AI就会制定计划、分步执行、自我测试、持续迭代,即使你关掉终端也会继续。本文详解/goal的工作原理、配置启用方法、常用命令(pause/resume/status/clear),以及如何写出高质量的目标描述让AI高效自主完成任务。

yueyeguzhuo的专栏 455

优化翼型形状的遗传算法实现

在每一代种群中,通过计算每个个体的适应度值,选择具有较高适应度值的个体,并使用交叉和变异算子对它们进行操作,从而生成新的个体。具体而言,我们将采用一个参数化的翼型模型,其中包括几何设计变量,如角度、弯曲和厚度等,以及性能指标,如升阻比和扭矩等。总之,本文提供了一个基于遗传算法的优化方法,用于寻找最优的翼型形状,并提供MATLAB源代码。需要注意的是,上述代码中的objFunc函数是一个示例性质的目标函数,实际应用中需要根据具体的问题进行修改。1.初始化一个随机的种群,其中每个个体代表一个参数化的翼型模型。

与其临渊羡鱼,不如退而结网 517

大厂面试官必问的Mysql锁机制

大厂面试官必问的Mysql锁机制

Jaemon 388

uniapp - 如何跟内嵌 web-view 组件内的网页交互,与 web-view 内嵌网页进行双向通信(uniapp 与 webview 网页之间的 “相互“ 传值)提供详细的示例代码及解决方案

uni-app如何实现在H5环境中与web-view中的网页交互通讯uniappuni-app 与 web-view内嵌网页 双向通信 如何跟内嵌web-view交互uniappAPP与webview子页面交互uniappAPP与webview子页面交互关于uni-app 使用 web-view 页面之间互相跳转、通信等问题uniapp的web-view嵌入网页,网页与uniapp通信webview如何与uniapp写的H5页面交互嵌套webview调用uniapp各种API组件实现H5和app通讯和交互

✅ 精选推荐文章 1万+

数据库表是不是锁住了_面试官问:请介绍一下MySQL数据库的锁机制?

推荐阅读:吊打面试官!MySQL灵魂100问,你能答出多少?为什么要加锁问题背景当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。要解决的问题多用户环境下保证数据库完整性和一致性锁是什么在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足。加锁是实...

weixin_29625619的博客 101

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

面试官:说一下MySQL中的锁机制吧

当查询的记录存在时,扫描到的二级索引记录加的是next-key lock,扫描到的第一个不符合条件的二级索引记录,next-key 锁会退化成间隙锁。RR隔离级别下,会存在幻读的问题,InnoDB为了解决可重复读隔离级别下的幻读问题,就引出了next-key 锁,是记录锁和间隙锁的组合。的范围查询,如果“等于”的等值查询的记录是存在于表中,那么该记录的索引中的 next-key 锁会。当查询的记录不存在时,扫描到第一条不符合条件的二级索引记录, next-key 锁会退化成间隙锁。

weixin_62633072的博客 3274

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

面试官:MySQL 锁机制详解?

本文详细解析了MySQL锁机制在Java面试中的重要性,涵盖共享锁、排他锁等分类,以及表锁、行锁等不同粒度。深入探讨了InnoDB的行锁实现原理(记录锁、间隙锁、MVCC)和死锁处理机制,并提供了SQL和Java代码示例。文章还列举了高并发交易、库存扣减等实际应用场景,帮助开发者掌握数据库并发控制核心知识,提升面试和实战能力。完整Java面试题库可通过文末链接获取。

huazaijake的博客 429

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

2022吊打面试官:MySQL你知道了哪些

最近整理一份关于MySQL常见面试题的 一般来讲在面试当中, 关于数据库相关的面试题频率出现比较高的几个关键词是SQL优化、索引、存储引擎、事务、死锁、乐观锁、悲观锁、关系型数据库和非关系数据库对比等等。 把这几个点问完基本也差不多10~20分钟了(一般一轮面试1小时左右), 基本上这些可以让面试官对你的数据库知识有一定的了解了。 如果你线上运维经验, 一般也会问一些比如数据库扩容, 如何给大表加索引, 如何在业务高峰时给一个大表添加字段等。 目录 一、数据库基础知识 1、平时My

qq_39652397的博客 1239

聊聊大厂面试官必问的 MySQL 锁机制

点击上方IT牧场,选择置顶或者星标技术干货每日送达前言前几天有粉丝和我聊到他找工作面试大厂时被问的问题,因为现在疫情期间,找工作也特别难找。他说面试的题目也比较难,都偏向于一两年的...

ITMuch的专栏 327
上一篇: MySQL高频面试题的灵魂拷问
下一篇: 「从零开始学SpringBoot」—如何开始使用?
java小望
博客等级 码龄5年 1粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值