当前位置: 首页 > news >正文

mysql 排它锁,共享锁

文章目录

        • 前言
        • 建立测试表
        • 测试前的准备工作
        • 行级锁
          • 表锁演示
          • 行级锁演示
        • 共享锁
        • 排它锁
        • 死锁
        • 死锁避免

前言

讲解基于innodb引擎
每次执行时候请 select @@autocommit 看看是不是等于0。每次执行完记得把两个命行执行后commit掉。
还有人评论共享锁,排它锁在哪里。我是真的无语了。

建立测试表

# 建表
create table user (
    id int auto_increment primary key,
    name varchar(10)
) engine = innodb default charset UTF8MB4;

# 插入测试数据
insert into user (`id`,`name`) values (1,"name_1"),(2,"name_2"),(3,"name_3"),(4,"name_4")

测试前的准备工作

开启两个mysql命令行,执行下面操作。下面的演示中使用了for update,是因为我们要使用当前读,
而不是使用快照读

# 先查看是否自动提交,1为自动提交
select @@autocommit

# 关闭自动提交,对当前命令行有效果
set autocommit = 0

# 每次演示完,进入下一个演示,请记得commit结束

行级锁

innodb默认支持行级锁。加锁是对索引加锁,如果不走索引,则退化成表锁

表锁演示
# 命令行1先执行,返回结果
# name 上没索引,造成锁表
select * from user where name = 'name_1' for update;

# 命令行2执行,等待
# 只有等命令行1的commit后才会执行
select * from user where id = 2 for update;
行级锁演示
# 命令行1
select * from user where id = 1 for update;
# 命令行2,ok
select * from user where id = 2 for update;

共享锁

使用 lock in share mode 加锁
多个事务共用一把锁,可以获取数据内容,但不能修改(需要先加锁的释放掉才能修改)

# 命令行1,commit 后命令行2才可修改成功
select * from user where id = 1 lock in share mode;
# 命令行2
select * from user where id = 1 lock in share mode;
update user set name = "name_2_new" where id = 1;
commit;

排它锁

使用 for update 加锁
只有当前事务才能进行读取和修改操作

# 命令行1
select * from user where id = 1 for update;
# 命令行2,要等待1commit
select * from user where id = 1 for update;
# 命令行1
select * from user where id = 1 for update;
# 命令行2,要等待1commit
update user set name = "new_name" where id = 1;

死锁

事务都在等待对方释放资源

# 1⃣️ 命令行1,先执行
select * from user where id = 1 for update;
# 2⃣️ 命令行2,执行
select * from user where id = 2 for update;
# 3⃣️ 命令行1,执行
select * from user where id = 2 for update;
# 4⃣️ 命令行2,执行
select * from user where id = 1 for update;

# 都在等待对方释放锁,所以死锁了
Deadlock found when trying to get lock; try restarting transaction

死锁避免

1 调整逻辑顺序,比如将上面死锁的演示顺序调整为 1324,这样只会出现等待,而不会死锁
2 降低事务级别,串行化
3 一般在事务中不使用悲观锁 for update,使用乐观锁代替
4 除了使用乐观锁代替,还能使用分布式锁代替

相关文章:

  • 煤炭行业生命周期分析,煤炭行业周期性特征
  • [SpringBoot系列]NoSQL数据层解决方案
  • 【通信原理】确知信号的性质分析与研究
  • Linux网络:网络层IP协议 链路层MAC协议
  • 猿创征文 |【SpringBoot2】快速上手SpringBoot
  • Linux的scp命令远程传输文件
  • antv x6让拖拽控件工具箱悬浮在画布上,工具箱区域鼠标按下不生成节点
  • matlab怎么训练神经网络,matlab神经网络训练方法
  • 「面经分享」小米java岗二面面经,已拿offer
  • 手把手教你给女朋友编写一个公众号定时推送(java版本)
  • 数据结构与算法--动态规划
  • 标准IO移动光标
  • 咕咕驴2022新版AI短视频一键换脸小程序源码/带流量主
  • 检查异常处理方式:1,抛出;2,捕获
  • 数组清空(bzero与memset)
  • SegmentFault for Android 3.0 发布
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • Hexo+码云+git快速搭建免费的静态Blog
  • JavaScript-Array类型
  • js对象的深浅拷贝
  • Laravel5.4 Queues队列学习
  • leetcode386. Lexicographical Numbers
  • Next.js之基础概念(二)
  • Python_OOP
  • React组件设计模式(一)
  • storm drpc实例
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • #if和#ifdef区别
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (12)Hive调优——count distinct去重优化
  • (3)(3.5) 遥测无线电区域条例
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (搬运以学习)flask 上下文的实现
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (转)visual stdio 书签功能介绍
  • (转)菜鸟学数据库(三)——存储过程
  • (转载)(官方)UE4--图像编程----着色器开发
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • ./configure,make,make install的作用
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .Net Core与存储过程(一)
  • .NET delegate 委托 、 Event 事件
  • .net Signalr 使用笔记
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .NET大文件上传知识整理
  • .NET牛人应该知道些什么(2):中级.NET开发人员