当前位置: 首页 > 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 实现)

相关文章:

  • [数据库之十四] 数据库索引之位图索引
  • Mac 平台获取地区标识符号
  • 2025最新免费视频号下载工具!支持Win/Mac,一键解析原画质+封面
  • 【NextPilot日志移植】整体功能概要
  • SpringBoot3 + Druid + DynamicDataSource + PgSQL 连接池优化方案
  • spring中RequestContextHolder
  • 【WEB3】区块链、隐私计算、AI和Web3.0——隐私计算(2)
  • AI赋能高频PCB信号完整性优化
  • Ubuntu上安装MySQL 8并配置Navicat远程连接
  • Redis如何实现分布式锁
  • CFCA受邀参加盛京银行手机银行7.0发布会
  • crontab
  • 5月8日星期四今日早报简报微语报早读
  • 红外遥控与NEC编码协议详解
  • C#学习7_面向对象:类、方法、修饰符
  • 【AI】DeepWiki 页面转换成 Markdown 保存 - Chrome 扩展
  • 【速通RAG实战:索引】5.RAG分块策略与Embedding技术
  • React -> AI组件 -> 调用Ollama模型, qwen3:1.7B非常聪明
  • 基础算法系列——树的入门
  • Linux_进程退出与进程等待
  • 马克思主义理论研究教学名师系列访谈|董雅华:让学生感知马克思主义理论存在于社会生活中
  • 盖茨:20年内将捐出几乎全部财富,盖茨基金会2045年关闭
  • 【社论】以法治力量促进民企长远健康发展
  • 国铁集团:铁路五一假期运输收官,多项运输指标创历史新高
  • 央行行长:债券市场“科技板”准备工作基本就绪,目前近百家市场机构计划发行超三千亿科技创新债
  • 正荣地产:公司控股股东已获委任联合清盘人