Mysql中锁的使用场景是什么

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中锁的使用场景是什么”相关内容,可点击进入Worktile网站相关频道,进行搜索与查询。

文章标题:Mysql中锁的使用场景是什么,发布者:亿速云,转载请注明出处:https://worktile.com/kb/p/15143

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
亿速云的头像亿速云认证作者
上一篇 2022年6月29日 下午11:49
下一篇 2022年6月29日 下午11:50

相关推荐

  • easyrecovery怎么恢复视频

    easyrecovery恢复视频的方法 1、选择恢复视频,点击下一步。 2、接着选择你需要恢复的硬盘进行扫描。 3、等待软件扫描完成。 4、经过扫描后可以直观的看到文件数,文件夹数,和可恢复数据数 5、找到你需要恢复的视频,右键恢复就可以了。 关于“easyrecovery怎么恢复视频”这篇文章的内…

    2022年9月26日
    36500
  • win8如何取消开机启动项

    win8取消开机启动项的方法 1、 点击电脑开始键,找到设置。 2、点击应用选项。 3、点进去之后这里有一个启动,点进去。 4、想要关闭的应用,这里点击后面的关闭就可以了。 关于“win8如何取消开机启动项”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频…

    2022年9月24日
    66300
  • Android三方依赖冲突Gradle中exclude如何使用

    一、场景 Android项目的开发过程中,我们项目中的gradle的dependencies闭包中会引入很多三方依赖库,引入的库越多,越容易产生库之间的依赖冲突。 列举冲突的场景: 1、同一个依赖库引入多个版本; 2、重复引入了同一个依赖库; 编译报错信息一般为:Program type alrea…

    2022年9月13日
    4.0K00
  • 电脑msr分区可不可以删除

    msr分区可以删除;msr分区是“Microsoft Reserved Partition”的缩写,是作为保留分区来使用,系统组件可以将MSR分区的部分分配到新的分区以供使用,msr分区不是必须的,可以被删除。 本教程操作环境:windows10系统、DELL G3电脑。 msr分区可以删除 MSR…

    2022年9月16日
    3.9K00
  • windows该内存不能为read如何解决

    解决该内存不能为read的方法 名列前茅种:内存不能为read工具下载 1、内存不能为read工具在网上有好多版本,小编用过小黑内存不能为read工具,感觉还不错。这款软件通过处理调用CMD指令逐步恢复此BUG,很好的解决了因软件或者系统本身原因产生的不能为read错误 2、双击即可完成修复,重启电…

    2022年9月2日
    60700
  • SqlServer怎么创建自动收缩事务日志任务

    1. 进入SSMS 点击展开sqlserver代理,右键点击“作业”,然后选择新建作业。 2. 填写名称 名称可以随便填写,只要能表示这次作业任务就行了。简洁明了,让自己后面能看懂。 所有者选择sa或者windows用户。如果需要远程操作,建议选择sa账户。windows账户只支持本地登陆后操作执行…

    2022年9月13日
    66900
  • SQL注入中宽字节注入是什么

    宽字节注入:是属于SQL注入的一种绕过方式 一、宽字节概念: 1、单字节字符集:所有的字符都使用一个字节来表示,比如 ASCII 编码(0-127) 2、多字节字符集:在多字节字符集中,一部分字节用多个字节来表示,另一部分(可能没有)用单个字节来表示。 3、UTF-8 编码: 是一种编码的编码方式(…

    2022年9月6日
    57200
  • 狩猎内网信息侦察工具Goddi怎么用

    Goddi Goddi 是 NetSPI 使用 Go 语言编写的工具,该工具有助于收集 Active Directory 域信息,被认为是 BloodHound、ADInfo、PowerSploit 和 windapsearch 等其他几种常见工具的替代方案。 Goddi 依赖对域控进行一系列自定义…

    2022年9月26日
    43200
  • coreldraw如何裁剪图片

    coreldraw裁剪图片的方法 1、打开软件,导入一张图片。 2、在页面左侧找到裁剪工具点击。 3、在图片上框选出你要裁剪的区域。 4、框选好之后,双击鼠标左键就成功裁好了。 以上就是关于“coreldraw如何裁剪图片”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若…

    2022年9月26日
    72200
  • Redis实现分布式锁的五种方法是什么

    1. 单机数据一致性 单机数据一致性架构如下图所示:多个可客户访问同一个服务器,连接同一个数据库。 场景描述:客户端模拟购买商品过程,在Redis中设定库存总数剩100个,多个客户端同时并发购买。 @RestControllerpublic class IndexController1 { @Aut…

    2022年9月15日
    1.0K00
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部