高并发场景下的数据库优化
- 软件开发
- 2025-09-10 23:15:03

在高并发系统中,数据库通常是性能瓶颈。面对高并发请求,我们需要采用合适的优化策略,以保证数据库的稳定性和高效性。本文将介绍数据库高并发问题的成因,并结合 Mybatis-Plus,探讨 乐观锁、悲观锁、高并发优化及数据库连接池优化 的最佳实践。
1. 数据库高并发问题分析 1.1 高并发数据库问题的常见表现 数据库连接耗尽:过多的并发请求导致数据库连接池资源被占满,新的请求无法获取连接。锁竞争严重:多个事务对同一行或同一表的数据竞争锁,导致等待时间变长,甚至发生死锁。读写压力过大:业务场景下 大量写操作(INSERT、UPDATE) 或 查询操作(SELECT) 导致数据库压力增大,影响系统响应时间。数据不一致:并发修改同一数据时,可能导致数据丢失或覆盖,产生 脏读、幻读、不可重复读 等问题。
2. 乐观锁与悲观锁的使用
在高并发场景下,数据库并发控制策略主要分为 乐观锁 和 悲观锁。 在高并发场景下,数据库并发控制策略主要分为 乐观锁 和 悲观锁。
2.1 乐观锁适用场景:适用于 读多写少 的场景,例如 订单支付状态修改、库存扣减 等。
实现方式:
通过 版本号机制(Version) 进行更新。在 UPDATE 时,带上 version 条件,只有 version 匹配时才更新成功,否则更新失败。Mybatis-Plus 乐观锁实现
在实体类中增加 @Version 注解 @Data @TableName("user") public class User { @TableId(type = IdType.AUTO) private Long id; private String name; private Integer age; @Version // 版本号字段 private Integer version; } 开启 Mybatis-Plus 乐观锁插件 在 MybatisPlusConfig 配置类中启用 乐观锁插件: @Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } } 更新时,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提高数据库连接管理效率
在高并发场景下,数据库优化是一个系统性工程。合理选择 乐观锁/悲观锁、批量插入、数据库连接池优化,可以极大提高数据库吞吐能力,确保系统在高并发下依然稳定高效!🚀
高并发场景下的数据库优化由讯客互联软件开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“高并发场景下的数据库优化”
 
               
               
               
               
               
               
   
   
   
   
   
   
   
   
  