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

【并发编程】MySQL锁及单机锁实现

目录

一、MySQL锁机制

1.1 按锁粒度划分

1.2 按锁功能划分

1.3 InnoDB锁实现机制

(1)记录锁(Record Lock)

(2) 间隙锁(Gap Lock)

(3) 临键锁(Next-Key Lock)

(4) 插入意向锁(Insert Intention Lock)

二、基于 JVM 本地锁实现,保证线程安全

2.1 线程不安全的分析

2.1.1 多线程并发访问(未加锁)

2.2 基于 synchronized 加锁访问

2.3 基于 synchronized 加锁访问

2.4 JVM 本地锁的缺陷

三、基于 MySQL 锁实现,保证线程安全问题

3.1 基于原子 SQL 实现

3.2 基于悲观锁实现(灵活多 SQL )

3.2.1 原生 SQL 实现

3.2.2 Java 代码实现

3.2.3 悲观锁优缺点

3.2.4 死锁演示

3.3 基于乐观锁实现(CAS)

3.3.1 原生SQL实现

3.3.2 Java 代码实现

3.3.3 乐观锁存在的问题

四、本地不同类型锁的总结


一、MySQL锁机制

1.1 按锁粒度划分

  • 表级锁​:锁定整张表

    • 优点:开销小,加锁快
    • 缺点:并发度低
    • 实现:LOCK TABLES语句或存储引擎自动加锁
  • 行级锁​:锁定单行记录

    • 优点:并发度高
    • 缺点:开销大,加锁慢
    • 实现:InnoDB通过索引实现
  • 页级锁​:锁定一页(16KB)

    • 折中方案,BDB引擎使用

1.2 按锁功能划分

  • 共享锁(S锁)​​:

    • 语法:SELECT ... LOCK IN SHARE MODE
    • 特性:多个事务可同时获取,但不能与排他锁共存
  • 排他锁(X锁)​​:

    • 语法:SELECT ... FOR UPDATE
    • 特性:独占锁,其他事务不能获取任何锁
  • 意向锁(Intention Lock)​​:

    • 表级锁,表示事务将要获取行锁
    • IS锁(意向共享锁):事务准备给行加S锁
    • IX锁(意向排他锁):事务准备给行加X锁

1.3 InnoDB锁实现机制

(1)记录锁(Record Lock)
  • 锁定索引中的单条记录
  • 实现方式:通过索引项加锁
(2) 间隙锁(Gap Lock)
  • 锁定索引记录间的间隙
  • 防止幻读问题
  • 示例:SELECT * FROM t WHERE id > 10 AND id < 20 FOR UPDATE
(3) 临键锁(Next-Key Lock)
  • 记录锁+间隙锁的组合
  • 锁定记录及记录前的间隙
  • InnoDB默认行锁算法
(4) 插入意向锁(Insert Intention Lock)
  • 特殊的间隙锁
  • 多个事务在相同间隙插入不同记录时不冲突

二、基于 JVM 本地锁实现,保证线程安全

2.1 线程不安全的分析

多线程环境下多个线程(并发用户访问)访问同一个共享资源,并对资源进行修改(触发了线程安全问题)。

接下来只关注 Service 层的逻辑实现

2.1.1 多线程并发访问(未加锁)

1. 创建多线程环境下生产级减库存案例

@Service
public class StockService {private Stock stock = new Stock();public void deduct(){stock.setStock(stock.getStock()-1);System.out.println("扣减成功,剩余库存:"+stock.getStock());}
}

2. 运行项目,通过 JMeter 进行并发测试

查看聚合报告,样本数量为 5000 次,吞吐量为 1900个事务/秒 左右。

3. 查看项目日志:发生超卖现象。

此时查看 MySQL 表中的 1001 商品编号的第一条记录,校验库存数量是否为0:

2.2 基于 synchronized 加锁访问

1. 修改减库存的方法,进行加锁操作:synchronized 直接修改方法(底层是基于 Monitor 实现)

http://www.xdnf.cn/news/341407.html

相关文章:

  • 【Android】动画原理解析
  • IT/OT 融合架构下的工业控制系统安全攻防实战研究
  • 【嵌入式开发-USB】
  • 王泫梓妍在户外拍摄的一组照片
  • 缓存套餐-03.功能测试
  • Spark缓存
  • 【前端基础】9、CSS的动态伪类(hover、visited、hover、active、focus)【注:本文只有几个粗略说明】
  • 5月8日星期四今日早报简报微语报早读
  • 【人工智能核心技术全景解读】从机器学习到深度学习实战
  • 什么是多模态大模型?为什么需要多模态大模型?
  • 兼具直连存储与分布式存储优势的混合存储方案
  • 轻量级证件照制作 AI 工具 HivisionIDPhotos 介绍
  • Android 查看 Logcat (可纯手机方式 无需电脑)
  • ZooKeeper工作机制与应用场景
  • 中国自动驾驶研发解决方案,第一!
  • SM2Utils NoSuchMethodError: org.bouncycastle.math.ec.ECFieldElement$Fp.<init
  • 【Electron】electron-vue 借助 element-ui UI 库助力桌面应用开发
  • 维吉尼亚密码C++实现
  • 责任链设计模式
  • 路由器断流排查终极指南:从Ping测试到Wireshark抓包5步定位法
  • Windows Server 2025 安装AMD显卡驱动
  • android.app.Fragment和androidx.fragment:fragment的区别
  • ActiveMQ 源码剖析:消息存储与通信协议实现(四)
  • 预训练模型实战手册:用BERT/GPT-2微调实现10倍效率提升,Hugging Face生态下的迁移学习全链路实践
  • 数据中台-数仓分层结构【Doris】
  • 【LunarVim】CMake LSP配置
  • 基于Kubernetes的Apache Pulsar云原生架构解析与集群部署指南(上)
  • python 上海新闻爬虫
  • Baumer工业相机堡盟工业相机的工业视觉中为什么偏爱“黑白相机”
  • 【前端基础】8、CSS的选择器