高并发场景下的数据库优化

news2025/3/7 4:03:13

在高并发系统中,数据库通常是性能瓶颈。面对高并发请求,我们需要采用合适的优化策略,以保证数据库的稳定性和高效性。本文将介绍数据库高并发问题的成因,并结合 Mybatis-Plus,探讨 乐观锁、悲观锁、高并发优化及数据库连接池优化 的最佳实践。


1. 数据库高并发问题分析

1.1 高并发数据库问题的常见表现

  • 数据库连接耗尽:过多的并发请求导致数据库连接池资源被占满,新的请求无法获取连接。
  • 锁竞争严重:多个事务对同一行或同一表的数据竞争锁,导致等待时间变长,甚至发生死锁。
  • 读写压力过大:业务场景下 大量写操作(INSERT、UPDATE)查询操作(SELECT) 导致数据库压力增大,影响系统响应时间。
  • 数据不一致:并发修改同一数据时,可能导致数据丢失或覆盖,产生 脏读、幻读、不可重复读 等问题。

2. 乐观锁与悲观锁的使用

在高并发场景下,数据库并发控制策略主要分为 乐观锁悲观锁
在高并发场景下,数据库并发控制策略主要分为 乐观锁悲观锁

2.1 乐观锁

适用场景:适用于 读多写少 的场景,例如 订单支付状态修改、库存扣减 等。

实现方式

  • 通过 版本号机制(Version) 进行更新。
  • UPDATE 时,带上 version 条件,只有 version 匹配时才更新成功,否则更新失败。

Mybatis-Plus 乐观锁实现

  1. 在实体类中增加 @Version 注解
@Data
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    
    @Version  // 版本号字段
    private Integer version;
}
  1. 开启 Mybatis-Plus 乐观锁插件
    MybatisPlusConfig 配置类中启用 乐观锁插件
@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}
  1. 更新时,Mybatis-Plus 自动维护版本号
@Autowired
private UserMapper userMapper;

public void updateUserAge(Long userId) {
    User user = userMapper.selectById(userId);
    user.setAge(user.getAge() + 1);
    userMapper.updateById(user); // Mybatis-Plus 会自动带上 version 字段
}

如果 version 发生变化,更新失败,需要重新读取数据再更新。


2.2 悲观锁

适用场景:适用于 写多读少、强一致性 场景,例如 金融交易、订单扣款 等。

实现方式

  • SELECT … FOR UPDATE:在事务内查询数据并加锁,防止其他事务修改数据。
  • 使用数据库本身的行锁(Row Lock)

示例:使用 FOR UPDATE 进行悲观锁控制

@Select("SELECT * FROM user WHERE id = #{id} FOR UPDATE")
User selectForUpdate(Long id);
  • 事务提交前,其他事务无法修改该行数据。
  • 适用于事务范围内需要严格一致性的操作。

缺点

  • 如果锁住的数据较多,会导致 大量事务等待,影响并发能力。

3. Mybatis-Plus 高并发优化实践

3.1 批量插入

在高并发写入场景下,逐条 INSERT 可能会导致 SQL 频繁执行,影响性能。Mybatis-Plus 提供了 批量插入 的方式:

@Autowired
private UserMapper userMapper;

public void batchInsertUsers(List<User> users) {
    userMapper.insertBatchSomeColumn(users);
}

注意insertBatchSomeColumn 需要开启 Mybatis-Plus 扩展插件。


3.2 避免 N+1 查询

问题:当查询列表数据时,可能会引发多次 SQL 查询:

List<Order> orders = orderMapper.selectList(null);
for (Order order : orders) {
    User user = userMapper.selectById(order.getUserId());
}

解决方案

  • 使用 IN 查询 一次性获取所有用户数据:
List<Long> userIds = orders.stream().map(Order::getUserId).collect(Collectors.toList());
List<User> users = userMapper.selectBatchIds(userIds);
  • 使用 Mybatis-Plus 关联查询
@Select("SELECT o.*, u.name as userName FROM orders o JOIN user u ON o.user_id = u.id WHERE o.id = #{orderId}")
OrderWithUser selectOrderWithUser(Long orderId);

4. 数据库连接池优化

数据库连接池(DataSource)是高并发优化的核心组件,推荐使用 Druid 或 HikariCP

4.1 HikariCP 连接池优化

application.yml 配置:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      minimum-idle: 10
      maximum-pool-size: 50
      idle-timeout: 30000
      max-lifetime: 1800000
      connection-timeout: 3000

参数解析

  • maximum-pool-size: 连接池最大连接数,通常设置为 CPU 核心数 * 2 + 1
  • minimum-idle: 最小空闲连接数。
  • connection-timeout: 获取连接的超时时间(建议不超过 3 秒)。
  • max-lifetime: 连接最大存活时间,防止长时间占用连接。

5. 总结

优化点方法适用场景
并发控制乐观锁 @Version读多写少,如库存扣减
悲观锁SELECT ... FOR UPDATE高一致性,如订单扣款
批量插入insertBatchSomeColumn()大批量数据插入
避免 N+1 查询IN 查询、Mybatis-Plus 关联查询避免多次查询
连接池优化HikariCP提高数据库连接管理效率

在高并发场景下,数据库优化是一个系统性工程。合理选择 乐观锁/悲观锁、批量插入、数据库连接池优化,可以极大提高数据库吞吐能力,确保系统在高并发下依然稳定高效!🚀

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

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

相关文章

IP-Guard软件设置P2P升级功能

日常使用IP-Guard软件遇到客户端升级&#xff0c;需要从服务器下载升级包&#xff0c;为了让快速升级&#xff0c;可以配置参数&#xff0c;具体设置见下图&#xff1a; 控制台—策略—定制配置—新增 关键字&#xff1a;obt_dislble_p2p2 内容&#xff1a;2

【Mac】git使用再学习

目录 前言 如何使用github建立自己的代码库 第一步&#xff1a;建立本地git与远程github的联系 生成密钥 将密钥加入github 第二步&#xff1a;创建github仓库并clone到本地 第三步&#xff1a;上传文件 常见的git命令 git commit git branch git merge/git rebase …

java后端开发day27--常用API(二)正则表达式爬虫

&#xff08;以下内容全部来自上述课程&#xff09; 1.正则表达式&#xff08;regex&#xff09; 可以校验字符串是否满足一定的规则&#xff0c;并用来校验数据格式的合法性。 1.作用 校验字符串是否满足规则在一段文本中查找满足要求的内容 2.内容定义 ps&#xff1a;一…

【TCP/IP协议栈】【传输层】端口号、套接字、多路复用/分解、网络字节序

参考资料&#xff1a; 前言&#xff1a; 总结&#xff1a; 【计算机网络】套接字&#xff08;应用层和传输层之间的接口&#xff09; 套接字是一个通用的通信接口抽象不仅限于TCP/IP协议族作为应用层和传输层之间的桥梁支持多种通信方式和协议族 套接字定义 在 TCP 或者 UDP…

【漫话机器学习系列】120.参数化建模(Parametric Modeling)

参数化建模&#xff08;Parametric Modeling&#xff09;详解 1. 引言 在数据建模和机器学习中&#xff0c;参数化建模&#xff08;Parametric Modeling&#xff09;是一种广泛应用的建模方法。它通过假设一个函数形式来表达变量之间的关系&#xff0c;并估算该函数的参数&am…

Web3 的未来:去中心化如何重塑互联网

Web3 的未来&#xff1a;去中心化如何重塑互联网 在这个信息爆炸的时代&#xff0c;我们正站在一个新的技术革命的门槛上——Web3。Web3 不仅仅是一个技术术语&#xff0c;它代表了一种全新的互联网理念&#xff0c;即去中心化。这种理念正在逐步改变我们对互联网的使用方式和…

DApp开发从入门到精通:以太坊/Solana公链生态实战解析

在区块链技术的推动下&#xff0c;去中心化应用&#xff08;DApp&#xff09;逐渐摆脱传统中心化后台的依赖&#xff0c;转向以智能合约为核心的全合约化开发模式。这种模式通过区块链网络的分布式特性&#xff0c;实现了数据存储、业务逻辑与用户交互的完全去中心化。 一、全合…

【计算机网络入门】TCP拥塞控制

目录 1. TCP拥塞控制和TCP流量控制的区别 2. 检测到拥塞该怎么办 2.1 如何判断网络拥塞&#xff1f; 3. 慢开始算法 拥塞避免算法 4.快重传事件->快恢复算法 5. 总结 1. TCP拥塞控制和TCP流量控制的区别 TCP流量控制是控制端对端的数据发送量。是局部的概念。 TCP拥…

【Maven】入门介绍 与 安装、配置

文章目录 一、Maven简介1. Maven介绍2. Maven软件工作原理模型图 二、Maven安装和配置1. Maven安装2. Maven环境配置3. Maven功能配置4. IDEA配置本地Maven软件 一、Maven简介 1. Maven介绍 https://maven.apache.org/what-is-maven.html Maven 是一款为 Java 项目管理构建、…

springbootWeb入门--创建springbootweb项目

步骤&#xff1a; 1.建立空工程 2.选择项目的jdk版本 3.在工程中建立模块&#xff0c;选择“spring initilazer”,类型勾选“maven” 4.勾选“spring web”之后&#xff0c;就无需再自行写dependcy了。 5.等待联网下载 6.生成的工程文件&#xff0c;如下绿色框中文件&…

vtk 3D坐标标尺应用 3D 刻度尺

2d刻度尺 : vtk 2D 刻度尺 2D 比例尺-CSDN博客 简介&#xff1a; 3D 刻度尺&#xff0c;也是常用功能&#xff0c;功能强大 3D 刻度尺 CubeAxesActor vtkCubeAxes调整坐标轴的刻度、原点和显示效果&#xff0c;包括关闭小标尺、固定坐标轴原点&#xff0c;以及设置FlyMode模…

Kylin麒麟操作系统服务部署 | NFS服务部署

以下所使用的环境为&#xff1a; 虚拟化软件&#xff1a;VMware Workstation 17 Pro 麒麟系统版本&#xff1a;Kylin-Server-V10-SP3-2403-Release-20240426-x86_64 一、 NFS服务概述 NFS&#xff08;Network File System&#xff09;&#xff0c;即网络文件系统。是一种使用于…

涨薪技术|持续集成Git使用详解

Git介绍 Git 是一个开源的分布式版本控制系统&#xff0c;用以有效、高速的处理从很小到非常大的项目版本管理。 Git 的特点&#xff1a; 分支更快、更容易。 支持离线工作;本地提交可以稍后提交到服务器上。 Git 提交都是原子的&#xff0c;且是整个项目范围的&#xff0c;…

批量对 Word 优化与压缩,减少 Word 文件大小

在编辑 Word 文档的时候&#xff0c;我们通常会插入一些图片或者一些样式&#xff0c;这可能会导致 Word 文档的体积变得非常的庞大&#xff0c;不利于我们对 Word 文档进行分享、传输或者存档等操作&#xff0c;因此我们通常会碰到需要优化或者压缩 Word 文档的需求。那如何才…

CSS定位详解上

1. 相对定位 1.1 如何设置相对定位&#xff1f; 给元素设置 position:relative 即可实现相对定位。 可以使用 left 、 right 、 top 、 bottom 四个属性调整位置。 1.2 相对定位的参考点在哪里&#xff1f; 相对自己原来的位置 1.3 相对定位的特点&#xff1…

DeepSeek、Grok 和 ChatGPT 对比分析:从技术与应用场景的角度深入探讨

文章目录 一、DeepSeek&#xff1a;知识图谱与高效信息检索1. 核心技术2. 主要特点3. 应用场景4. 实际案例 二、Grok&#xff1a;通用人工智能框架1. 核心技术2. 主要特点3. 应用场景4. 实际案例 三、ChatGPT&#xff1a;聊天机器人与通用对话系统1. 核心技术2. 主要特点3. 应用…

【万字长文】基于大模型的数据合成(增强)及标注

写在前面 由于合成数据目前是一个热门的研究方向&#xff0c;越来越多的研究者开始通过大模型合成数据来丰富训练集&#xff0c;为了能够从一个系统的角度去理解这个方向和目前的研究方法便写了这篇播客&#xff0c;希望能对这个领域感兴趣的同学有帮助&#xff01; 欢迎点赞&…

MacBook上API调⽤⼯具推荐

在当今的软件开发中&#xff0c;API调用工具已经成为了开发者不可或缺的助手。无论是前端、后端还是全栈开发&#xff0c;API的调试、测试和管理都是日常工作中的重要环节。想象一下&#xff0c;如果没有这些工具&#xff0c;开发者可能需要手动编写复杂的CURL命令&#xff0c;…

【数据结构】LRUCache|并查集

目录 一、LRUCache 1.概念 2.实现:哈希表双向链表 3.JDK中类似LRUCahe的数据结构LinkedHashMap &#x1f525;4.OJ练习 二、并查集 1. 并查集原理 2.并查集代码实现 3.并查集OJ 一、LRUCache 1.概念 最近最少使用的&#xff0c;一直Cache替换算法 LRU是Least Recent…

初识Qt · 信号与槽 · 基础知识

目录 前言&#xff1a; 信号和槽初识 两个问题 前言&#xff1a; 本文我们正式开始介绍信号与槽这个概念&#xff0c;在谈及Qt中的信号与槽这个概念之前&#xff0c;我们不妨回顾一下Linux中的信号&#xff0c;比如发生了除0错误&#xff0c;OS就会给该进程发送一个信号&am…