深入了解Mysql中的锁,聊聊使用场景!

本篇文章带大家了解一下mysql中的锁,搞懂共享锁、排他锁、悲观锁、乐观锁,并聊聊使用场景,希望对大家有所帮助!

深入了解Mysql中的锁,聊聊使用场景!

一、常见锁类型

表级锁,锁定整张表页级锁,锁定一页行级锁,锁定一行共享锁,也叫S锁,在MyISAM中也叫读锁排他锁,也叫X锁,在MyISAM中也叫写锁悲观锁,抽象性质,其实不真实存在乐观锁,抽象性质,其实不真实存在

深入了解Mysql中的锁,聊聊使用场景!
常见锁类型

二、Mysql引擎介绍

其实mysql中的引擎有很多种类,其中InnoDB和MyISAM引擎最常用在mysql5.5版本前默认使用MyISAM引擎,之后使用InnoDB引擎查看数据库引擎命令如下

show variables like '%storage_engine%';

三、常用引擎间的区别 

MyISAM 操作数据都是使用的表锁,你更新一条记录就要锁整个表,导致性能较低,并发不高。当然同时它也不会存在死锁问题。

而 InnoDB 与 MyISAM 的最大不同有两点:一是 InnoDB 支持事务;二是 InnoDB 采用了行级锁。

在 Mysql 中,行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql 语句操作了主键索引,Mysql 就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。

InnoDB 行锁是通过给索引项加锁实现的,如果没有索引,InnoDB 会通过隐藏的聚簇索引来对记录加锁。也就是说:如果不通过索引条件检索数据,那么InnoDB将对表中所有数据加锁,实际效果跟表锁一样。因为没有了索引,找到某一条记录就得扫描全表,要扫描全表,就得锁定表。

四、共享锁与排他锁

数据库的增删改操作默认都会加排他锁,而查询不会加任何锁。

共享锁:对某一资源加共享锁,自身可以读该资源,其他人也可以读该资源(也可以再继续加共享锁,即 共享锁可多个共存),但无法修改。要想修改就必须等所有共享锁都释放完之后。

排他锁:对某一资源加排他锁,自身可以进行增删改查,其他人无法进行任何操作。

//共享锁select * from 表名 lock in share mode//排他锁select * from 表名 for update

五、排他锁的实际应用

这里我们以两个操作数据库的请求为例,假设这两个请求分别为T1和T2假设T1为查询请求,而T2为更新数据请求,在T1查询很长时间的时候,还没有返回结果,但是这时候T2过来请求更新了这个流程应该是: T1运行加共享锁、T2运行、发现T1未完成等待其完成、T1完成、T2开始执行T2之所以要等待,是因为T2执行更新的时候需要给表加排他锁,但是数据库规定,不能在同一资源上同时共存这两种锁,所以T2必须等T1执行完,释放锁后,才可以正常操作

T1: select * from 表名 lock in share mode //假设还未返回结果T2: update 表名 set name='autofelix'

六、共享锁的实际应用

如果T1和T2都是执行的查询,也就是都加共享锁这时候就不用等待,可以立马执行因为同一资源上可以同时存在多个共享锁,也被称为,共享锁与共享锁兼容意味着共享锁不阻止其他人同时读取资源,但是阻止其他人修改资源

T1: select * from table lock in share modeT2: select * from table lock in share mode

七、死锁的发生

假设T1和T2都同时执行2个资源操作,分别是查询和更新数据假设T1和T2同时达到select,T1对表加共享锁,而T2也加上了共享锁当T1的select执行完毕,准备执行update时根据锁机制,T1的共享锁必须升级到排他锁才可以执行接下来的update操作在升级排他锁之前,必须等T2的共享锁释放,同理,T2也在等T1的共享锁释放于是都在等待对方的锁释放,导致程序卡死,这种情况就是死锁

T1: 开启事务,执行查询更新两个操作     select * from table lock in share mode     update table set column1='hello'T2: 开启事务,执行查询更新两个操作     select * from table lock in share mode     update table set column1='world'

八、另一种发生死锁的情景

 当T1和T2都是只执行更新语句的时候如下程序所示,这种语句非常的常见,很多人觉得他会产生死锁,其实要看情况如果id是主键,由于主键机制,并不需要全表扫描,直接可以更新当前数据,所以不会产生死锁如果id是普通字段,那么当T1加上排他锁之后,T2为了找到id=20条数据,必须进行全表扫描,当他扫到第10条的时候,发现这里有排他锁,导致全表扫描进行不下去,就会导致等待

T1: begin     update table set content='hello' where id=10T2: begin     update table set content='world' where id=20

九、死锁的解决方式

就是让T1和T2顺序执行,比如T1在执行完select后,立马给自身加上排他锁,这样T2不得不等待T1执行完才能继续但是如果有很多请求过来的话,都必须等待,这对用户特别的不友好所以,某些数据库引入了另一种方式,叫做更新锁,这里mysql除外,不存在更新锁更新锁其实就是排他锁的另一种实现,只是他允许其他人读的同时加共享锁,但是不允许其他操作,除非释放了更新锁流程大概如此: T1执行完select加上更新锁,T2执行查询完,准备加更新锁,发现已经有了,就等待,其他请求过来,如果查询是不受影响的,但是更新才等待这相比上面的查询也要等待增加了效率

T1: begin     select * from table for update     update table set content='hello'T2: begin     select * from table for update     update table set content='world'
T1: begin     select * from table [加更新锁操作]     update table set content='hello'T2: begin     select * from table [加更新锁操作]     update table set content='world'

十、意向锁和计划锁

计划锁与程序猿无关,不需要了解意向锁,Innodb特有,分为意向共享锁和意向排他锁意向共享锁: 表示事务获取共享锁时,必须先得获取该表的意向共享锁意向排他锁: 表示事务获取排他锁时,必须先得获取该表的意向排他锁我们知道要对整个表加锁,必须保证表内不存在任何锁如果一行行的去检查是否加锁,效率必然极低,这时候可以检测意向锁是否被占用即可

十一、乐观锁和悲观锁

乐观锁和悲观锁都是针对select而言的比如在商品抢购中,用户购买后库存需要减1,而很多用户同时购买时,读出来的库存数量一样,然后多个用户同时用该库存去减1这种做法必然会出现很大的漏洞,如果向在淘宝,京东出现这种情况,你就可以打包回家种地了这种情况如何解决呢,其实可以使用悲观锁进行解决,说白了也就是排他锁用户进来查库存的时候,就加上排他锁,等他所有操作完成后,再释放排他锁,让其他人进来不让用户等待,就可以使用乐观锁方式解决,乐观锁一般靠表的设计和时间戳来实现一般是在表中添加version或者timestamp时间戳字段这样就会保证如果更新失败,就表示有其他程序更新了数据库,就可以通过重试解决

update table set num=num-1 where id=10 and version=12

【相关推荐:mysql视频教程】

以上就是深入了解Mysql中的锁,聊聊使用场景!的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/172444.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月1日 03:13:51
下一篇 2025年11月1日 03:15:18

相关推荐

  • 不同C++框架在特定领域的专业化和适用性对比

    不同的 c++++ 框架针对特定领域进行了专业化,以优化性能和易用性。对于 web 开发,boost.asio 以其轻量级和跨平台能力脱颖而出。用于 gui 开发的 qt 提供了丰富的功能和跨平台支持,而 qtsql 简化了数据库访问。poco 在网络编程中很突出,openmp 在并行计算中表现出色…

    2025年12月18日
    000
  • C++ 框架如何优化大型项目中资源管理和性能

    c++++ 框架通过资源管理和性能优化,提升了大型项目的效率:资源管理优化:通过资源池和智能指针管理资源,优化分配和释放操作。性能优化:利用并发编程和内存管理库,实现跨平台并发编程和提升内存管理性能。 C++ 框架:优化大型项目中资源管理和性能 大型 C++ 项目经常面临资源管理和性能问题。为了解决…

    2025年12月18日
    000
  • C++ 框架性能基准:与其他语言和平台的比较

    基准测试结果表明,c++++ 框架在 http 请求处理和数据库查询方面表现优异,boost.asio 适用于高并发连接,cpp-httplib 和 libuv 具有较低延迟。开发人员应根据不同场景选择最合适的框架。 C++ 框架性能基准:与其他语言和平台的比较 引言 性能是任何软件应用程序的关键方…

    2025年12月18日
    000
  • C++ 框架在网络安全领域的应用:提升网络抵御能力与威胁防御

    c++++ 框架在网络安全中广泛应用,提升网络抵御和威胁防御能力:高性能:c++ 速度和效率使其适合构建实时网络安全应用。内存管理:c++ 提供对内存的细粒度控制,确保安全和资源高效。跨平台支持:c++ 可在多种平台编译,便于构建跨平台安全解决方案。应用包括:入侵检测系统、防火墙、恶意软件分析和取证…

    2025年12月18日
    000
  • C++ 框架的学习指南:快速上手

    对于使用 c++++ 框架,本指南提供了分步指导,包括:了解基础知识:熟悉框架概念和 oop 原则。探索框架功能:容器、算法、线程管理、网络操作和数据库集成。实战案例:创建一个文件管理程序,演示框架的使用。扩展知识:探索其他框架、参与社区和练习项目。 C++ 框架的学习指南:快速上手 随着 C++ …

    2025年12月18日
    000
  • C++ 框架设计中实现代码重用的技术

    在 c++++ 框架设计中,实现代码重用的技术包括:模板方法模式:定义算法大纲,由子类定义具体步骤。策略模式:分离算法实现和使用对象,提高灵活性。工厂方法模式:创建对象的方法由子类实现,允许创建不同类型对象。抽象工厂模式:创建相关对象家族的方法,无需指定具体类,促进松耦合。单例模式:确保类只有一个实…

    2025年12月18日
    000
  • c++是什么语言

    C++ 是一种通用、面向对象、跨平台的编程语言,由比雅尼·斯特劳斯特鲁普开发于 1985 年。它具有面向对象、跨平台、高效、可扩展和低级控制等特点。C++ 被广泛应用于开发操作系统、数据库管理系统、游戏引擎、网络应用程序和大型企业软件。其优点包括效率高、可移植性好、面向对象和强大;缺点则包括复杂性、…

    2025年12月18日
    000
  • C++ 开源库指南:探索丰富的库资源,拓展编程能力

    c++++开源库为开发者提供了丰富的工具,包括:boost库:提供算法和数据结构,可用于字符串操作和图表处理。eigen:线性代数库。opencv:计算机视觉和机器学习库。qt:跨平台gui框架。mysql connector:与mysql数据库交互的库。wxwidgets:图形用户界面库。选择最合…

    2025年12月18日
    000
  • c++怎么连接数据库

    在C++中,可以使用ODBC或第三方库连接到数据库。ODBC步骤:初始化环境,连接到DBMS。其他库:MySQL Connector/C++、PostgreSQL libpq++、SQLite3,根据数据库类型和需求选择库。 C++连接数据库 在C++中连接数据库,可以使用标准的C++数据库连接库(…

    2025年12月18日
    000
  • 在 C++ 生态系统中,如何选择合适的库和框架?

    在 c++++ 生态系统中进行库和框架选择时,应考虑功能、性能、稳定性、社区支持和许可证等因素。实战案例包括 qt(图形库)、rapidjson(json 库)、boost.asio(网络库)和 mysql-connector-cpp(数据库连接库)。使用库管理器和仔细研究文档有助于做出明智的选择。…

    2025年12月18日
    000
  • 学习C++ Web开发所需的技能和资源有哪些?

    c++++ web 开发需要掌握 c++ 编程基础、网络协议和数据库知识。必备资源包括 cppcms、pistache 等 web 框架,cppdb、pqxx 等数据库连接器,以及 cmake、g++、wireshark 等辅助工具。通过学习实战案例,如创建简单的 http 服务器,可以开启 c++…

    2025年12月18日
    000
  • c++属于前端还是后端

    C++ 既可用于前端(用户界面创建)也可用于后端(服务器端逻辑处理),因为它强大且高效,支持多范例编程。决定因素包括应用类型、性能要求和开发团队技能。 C++:前端还是后端? C++ 既可以用于前端开发,也可以用于后端开发。因此,它不属于前端或后端的单一类别。 前端开发 涉及用户界面(UI)的创建,…

    2025年12月18日
    000
  • Dapper如何封装通用仓储 Dapper Repository模式实现方法

    Dapper通用仓储应借鉴EF思想而非照搬,核心是泛型约束+手写SQL灵活性:定义IRepository接口(GetById/Find/Insert/Update/Delete),实现类通过特性识别主键与列映射,动态生成安全SQL,支持事务参数,分页由具体方法处理,查询逻辑下沉至具体仓储,连接由DI…

    2025年12月17日
    000
  • Dapper中[Key]和[Table]特性有什么用 Dapper.Contrib特性详解

    [Table] 和 [Key] 是 Dapper.Contrib 中用于实体映射的核心特性:[Table] 标注类以指定对应数据库表名,避免默认复数推导错误;[Key] 标注自增主键属性,插入时忽略该字段并回填生成值;非自增主键须用[ExplicitKey]。 [Table] 和 [Key] 是 D…

    2025年12月17日
    000
  • EF Core如何执行异步操作 EF Core异步方法(SaveChangesAsync)教程

    EF Core异步方法(如SaveChangesAsync)通过释放线程提升高并发吞吐量,并非提速魔法;仅当底层驱动支持异步I/O(如SqlClient、Npgsql)时才真正异步,ToListAsync等是真异步,Where等LINQ构建操作是同步的,需避免混用同步终结符及伪异步写法。 EF Co…

    2025年12月17日
    000
  • EF Core如何自定义表名和列名 EF Core ToTable和HasColumnName方法

    EF Core 中通过 ToTable 和 HasColumnName 自定义表名与列名,优先级高于约定;ToTable 支持指定表名、架构及分表,HasColumnName 用于适配下划线命名、关键字等场景,二者均需在 OnModelCreating 中配置。 EF Core 中自定义表名和列名,…

    2025年12月17日
    000
  • C#如何进行数据库分片 ShardingSphere-Proxy .NET客户端用法

    ShardingSphere-Proxy 作为兼容 MySQL/PostgreSQL 协议的透明代理,.NET 应用只需使用 MySqlConnector 或 Npgsql 等标准 ADO.NET 驱动连接其地址(如 127.0.0.1:3307),即可透明执行分片路由,无需官方 SDK 或修改业务…

    2025年12月17日
    000
  • Dapper在Blazor WebAssembly中怎么用 Dapper与Blazor WASM

    Dapper不能在Blazor WebAssembly中直接使用,因其依赖的IDbConnection、数据库驱动和底层网络I/O在浏览器沙箱中不可用;正确方式是将Dapper部署在ASP.NET Core后端,前端通过HttpClient调用REST API获取JSON数据。 不能直接在Blazo…

    2025年12月17日
    000
  • C# Entity Framework Core中的迁移(Migrations) – 数据库架构的版本控制

    迁移是EF Core数据库版本控制机制,通过add-migration生成Up/Down方法脚本,update-database执行并记录至__EFMigrationsHistory表;开发中需及时生成、检查脚本、避免冲突;生产环境应导出SQL交DBA审核,禁用业务逻辑;注意重命名、多上下文等特殊处…

    2025年12月17日
    000
  • .NET中的LINQ to SQL和LINQ to Entities有什么区别?为什么EF Core是未来的方向?

    LINQ to SQL是专为SQL Server设计的轻量级ORM,简单高效但功能有限;1. LINQ to Entities作为Entity Framework的一部分,支持多数据库、复杂映射和模型优先开发,更具灵活性;2. EF Core是现代数据访问技术,跨平台、高性能、支持NoSQL,集成最…

    2025年12月17日
    000

发表回复

登录后才能评论
关注微信