MySQL中的表锁,行锁,排它锁,共享锁

表锁与行锁


1 ) 概念

  • 在使用mysql的时候,如果同时向 mysql 里边批量进行更新, 插入删除动作
  • 数据库里的数据不会出问题, 在 mysql内部,它其实自带了一个锁的功能
  • 而它内部有的是用了锁,有的没有用锁,没用锁的需要咱们利用锁来自行处理
  • mysql 从范围的角度来讲,支持表锁行锁
    • 表锁: 把整个表锁住
      • 你对这张表的任意行在做操作,你都得阻塞住
      • 还有就是, 占用这把锁的那个人处理完了下一个才能进来
    • 行锁: 它只锁了某一行
      • 表里的某一行, 比如你操作申请到锁了,下一个人来处理这一行, 它就会阻塞住
      • 如果下个人处理的是别的行,是允许的
    • 一般而言,行级锁是更好一些的锁
      • 因为我用哪个数据,我就锁住哪些数据即可
      • 当然也会有一些特殊的情况需要表级锁
  • 创建mysql的表的时候,是可以指定引擎的
    • Myisam 引擎: 只支持表锁,不支持行锁
      • 无论怎么加锁都是行锁
    • InnoDB 引擎: 支持行锁和表锁
      • 如果进行搜索时,利用索引的形式去搜,也就是命中索引
      • 搜到的某一行数据或某些个数据,它就可以利用行锁
      • 如果搜索的时候没有用到索引,比如说全表扫描
      • 那它会对整个表都锁住,就应用表锁了
  • 为了能够去用锁的时候,力度更细,InnoDB 是一个很好的选择
  • 所以,项目开发中,我们都选择去使用 InnoDB 引擎
  • 对 InnoDB 引擎创建的表,如果对这张表进行 update、insert、delete 做行为内部
  • 实际上它会先申请锁,然后再去执行,执行完,再释放锁
  • 如果很多人都在执行update操作,内部会把锁加上,不会造成数据混乱的问题
  • 它内部一定会排着队,逐个执行的
  • 但要执行 select,默认情况下,不会加锁,因为查询,拿过来加锁,没什么用
  • 如果以后在特定的条件,就需要查询的时候人为申请一把锁也是可以的
  • 它的使用规范是: 基于事务 + 特殊语法来实现

排它锁和共享锁

  • mysql 按照类型分,可分为 排它锁共享锁

  • 先创建一张表

    create table `L1`(`id` int(11) not null auto_increment,`name` varchar(255) default null,`count` int(11) default null,primary key (`id`)
    ) engine=innodb default charset=utf8;
    
  • 在这张表中操作 insert 很多数据,这里就不做操作了

1 ) 排它锁

  • 主要语法 for update, 示例

    begin; -- 或 start transaction;select * from L1 where name='wang' for update; -- 注意,这里name不是索引,使用表锁
    commit; -- 事务结束,锁释放
    
    begin;select * from L1 where id=1 for update; -- 注意,这里id是索引,使用行锁
    commit;
    
  • 如果事务不结束,其他人操作,都会受到阻塞,进行不下去

  • 需要等到本人commit之后,才能结束锁,其他人才能继续

应用场景

  • 抢购与库存减量
  • update 操作默认加锁,如果当还剩最后一件,再执行就会出问题,会出现 -1 的问题
  • 这样是不合适的
    update goods set count=count-1 where id=3
    
  • 解决方案是使用排它锁,如下

sql操作示例

begin;
select count from goods where id=3 for update;
-- 获取个数进行判断
if 个数 > 0:update goods set count=count-1 where id=3;
else:-- 抢光了的处理
commit;

py操作

import pymysql
import threadingdef task():# 建立连接conn = pymysql.connect(host='xxx.xxx.xxx.xxx', port=3306, user='root', password='xxxx', charset='utf8', db='userdb');# 限定结果格式,如下面的 fetchone 后,是这样的格式: { id: 1, age: 10 }# 如果是 fetchall, 则是这样的格式 ({ id: 1, age: 10 }, { id: 2, age: 11 })cursor = conn.cursor(pymysql.cursors.DictCursor)conn.begin() # 开启事务cursor.execute('select id, age from tran where id=2 for update') # 排它锁result = cursor.fetchone()current_age = result['age']if current_age > 0:cursor.execute('update tran set age==age-1 where id=2')else:print('已售完')conn.commit()cursor.close()conn.close()def run():# 创建5个线程, 都去执行 taskfor i in range(5):t = threading.Thread(target=task)t.start()if __name__ == '__main__':run()

2 ) 共享锁

主要语法是: lock in share mode

sql 用法示例

begin;select * from L1 where name='xxx' lock in share mode; -- name列不是索引,使用表锁
commit;begin;select * from L1 where id=1 lock in share mode;    -- id列是索引 (行锁)
commit;

和排它锁的区别是: 加锁之后,其他可读,不可写

场景举例

  • 目前有 A 和 B 两张锁
  • 需要在 A 表中插入一条数据,插入前需要确保 B 表中相关的一条数据存在
  • 但是,很可能在A插入的时候,B中的关键数据被删除
  • 这时候就可以用 共享锁 防止B中相关数据被删除

sql 实现

begin;select * from B where id=1 lock in share mode;    -- id列是索引 (行锁)insert into A(name) values('wang');
commit;
  • 一定要注意这一点:加锁之后,可以读,不可写(update, delete, insert)
  • 实际上应用场景不多

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/595214.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

宋仕强论道之华强北后山寨手机时代(三十六)

今天继续讲华强北山寨手机,跟手机配套周边产品。华强北,作为中国电子产品的集散地和创新中心,一直以来都是电子产品和数码产品的聚集地。在早期,赛格市场以其走私、翻新的电脑和电脑周边产品而闻名。赛格大厦以前5楼以上都是做电脑…

使用Android 协程代替Handler

在 Android 开发中,我们经常需要处理异步任务,例如网络请求、数据库访问、耗时计算等等。为了在处理异步任务时能够方便地更新 UI,Android 提供了 Handler 类。然而,在使用 Handler 时,我们需要处理一些繁琐的问题,例如线程间通信和内存泄漏。为了简化这些问题,Google 在…

乒乓球廉价底板评测之五F勒布伦打法讨论

菲利克斯勒布伦的直拍打法让直板又焕发了青春,那他的打法又有什么特点呢?和中国众多直板选手的区别在哪呢?这篇微博我们简单分一下。 首先说下他的器材,纤维板中置碳,淘宝上的版本是碳在大芯两侧,是七层板&…

Unity中URP下统一不同平台下的z值

文章目录 前言一、ComputeFogFactor 来计算雾效混合因子二、UNITY_Z_0_FAR_FROM_CLIPSPACE 来统一计算不同平台下的Z值1、DirectX平台2、GL平台下(在Unity.2022.LTS下,该功能没有完善)3、Opengl下 前言 在之前的文章中,我们实现了URP下的雾效…

go.mod与module

在 Go 语言的项目中,go.mod 文件是 Go Modules 依赖管理系统的核心文件之一。在 go.mod 文件中,module 声明是用来定义当前项目的模块路径的。模块路径是项目中包的导入路径的前缀。下面是关于 go.mod 文件中 module 声明的详细介绍: module…

Pointnet++改进:在特征提取模块加入NAMAttention注意力机制,有效涨点

简介:1.该教程提供大量的首发改进的方式,降低上手难度,多种结构改进,助力寻找创新点!2.本篇文章对Pointnet++特征提取模块进行改进,加入NAMAttention注意力机制,提升性能。3.专栏持续更新,紧随最新的研究内容。 目录 1.理论介绍 2.修改步骤 2.1 步骤一

Base64的理解及优缺点?png8、png16、png32的区别,png 的压缩原理?如何优化图片,网页制作会用到的图片格式有哪些?优化大量图片加载的方法?

Base64的理解 Base64是一种将任意二进制数据转换为纯文本的编码方式,它可以将二进制数据转换为普通文本,以便在网络上更方便地传输和存储数据。常被用于在文本协议下传输非文本文件,以及在URL中传递数据等场景。它将3个8位字节转为4个6位字节…

电动汽车BMS PCB制板的技术分析与可制造性设计

随着电动汽车行业的迅猛发展,各大厂商纷纷投入巨资进行技术研发和创新。电动汽车的核心之一在于其电池管理系统(Battery Management System, BMS),而BMS的心脏则是其印刷电路板(PCB)。通过这篇文章探讨电动…

Python字符串的判断

Python字符串的判断: 以下代码演示了Python字符串的判断: 实例 # Filename : test.py # author by : www.dida100.com # 测试实例一 print("测试实例一") str "dida100.com" print(str.isalnum()) # 判断所有字符都是数字或者字…

Graphics Control

Graphics Control提供了一个易于使用的图形设置管理解决方案,帮助您加快开发。它附带了一个常用设置库,如分辨率、垂直同步、全屏模式、光晕、颗粒、环境光遮挡等。我们的可自定义设置面板UI预制件为您提供了一个可用的UI面板,支持完整的游戏手柄和键盘输入。图形控制还附带…

version `GLIBCXX_3.4.21‘ not found

现象 今天在运行pytorch时报错了 version GLIBCXX_3.4.21‘ not found原因 centos7当前的gcc版本太老 ,里面的动态链接库没有GLIBCXX_3.4.21 排查 执行命令 检查动态库 strings /usr/lib64/libstdc.so.6 | grep GLIBCGLIBCXX_3.4 GLIBCXX_3.4.1 GLIBCXX_3.4.2 GLIBCXX_3.…

Spark---RDD介绍

文章目录 1.Spark核心编程2.RDD介绍2.1.RDD基本原理2.2 RDD特点1.弹性2.分布式 :数据存储在大数据集群的不同节点上3.数据集 :RDD封装了计算逻辑,并不保存数据4.数据抽象 :RDD是一个抽象类,具体实现由子类来实现5. 不可…

CCF模拟题 202312-1 仓库规划

问题描述 试题编号: 202312-1 试题名称: 仓库规划 时间限制: 1.0s 内存限制: 512.0MB 问题描述: 输入格式 输出格式 样例输入 4 2 0 0 -1 -1 1 2 0 -1样例输出 3 1 0 3样例解释 Java实现代码: import …

macbook录屏快捷键大全,教你快速录制视频

“有人知道macbook电脑有录屏快捷键吗,现在录屏的速度太慢了,每次打开都要浪费不少时间,要是有录屏快捷键,应该会快很多,有哪位大佬知道吗?教教我!” 无论是在工作还是生活中,电脑已…

生活中危险的气体:一氧化碳与二氧化碳中毒的症状及安全预防措施

一氧化碳和血红蛋白亲和力超过氧气,会占用血红蛋白,导致缺氧。 二氧化碳会和血浆结合,导致血液pH值不正常,抑制呼吸,导致窒息。 通俗点说:一氧化碳是中毒,二氧化碳则是窒息。 一氧化碳中毒 …

基于 Docker 搭建交叉编译环境

本文主要介绍如何使用 Docker 搭建交叉编译环境 关于 docker 交叉编译环境,已经有人做成项目开源了。我们只需使用即可 # 获取 linux-arm64 镜像 docker pull dockcross/linux-arm64# 该镜像不能直接运行, 需要间接运行,我是真的服了 # 根据提示, 将运行…

通过Vue自定义指令实现前端埋点

在营销活动中,通过埋点可以获取用户的喜好及交互习惯,从而优化流程,进一步提升用户体验,提高转化率。 在之前的埋点方案实现中,都是在具体的按钮或者图片被点击或者被曝光时主动通过事件去上报埋点。这种方法在项目中…

K8Spod组件

一个pod能包含几个容器 一个pause容器(基础容器/父容器/根容器) 一个或者多个应用容器(业务容器) 通常一个Pod最好只包含一个应用容器,一个应用容器最好也只运行一个业务进程。 同一个Pod里的容器都是运行在同一个node节点上的,并且共享 net、…

javaweb学习笔记

JSP 动态网页,指的是随时间、地点、用户操作改变的网页 架构 CS架构 client-server 缺点:每一台客户端都需要安装客户端软件,如果升级全要升级,如果坏了就得维护 优点:响应快,界面美观 BS架构 browser-…

Zookeeper集群 + Kafka集群的详解与部署(以及Filebeat+Kafka+ELK )

zookeeperkafka.txt Zookeeper概述 Zookeeper是一个分布式的开源协调服务,用于管理和维护大型分布式系统中的配置信息、命名服务、状态同步等。它提供了一个可靠的分布式环境,用于协调多个节点之间的通信和管理。 数据结构 ZooKeeper数据模型的结构与…