程序员必备的十大技能(进阶版)之高性能数据库实战(四)

简介: 教程来源 http://oplhc.cn/ 本节详解HikariCP高性能连接池调优(含最小空闲、最大连接数等核心参数及动态扩容实践)、连接泄漏检测机制,以及MySQL事务隔离级别、MVCC原理、行锁/间隙锁/死锁排查与事务最佳实践,覆盖高并发场景下的稳定性与性能关键点。

五、数据库连接池调优

5.1 HikariCP配置详解(当前性能最强)

spring:
  datasource:
    hikari:
      # 核心配置
      minimum-idle: 10               # 最小空闲连接数
      maximum-pool-size: 20          # 最大连接池大小(公式:((core_count * 2) + effective_spindle_count))
      connection-timeout: 30000      # 连接超时(ms)
      idle-timeout: 600000           # 空闲超时(10分钟)
      max-lifetime: 1800000          # 连接最大生命周期(30分钟)

      # 性能优化配置
      connection-test-query: SELECT 1
      validation-timeout: 5000
      leak-detection-threshold: 60000  # 连接泄漏检测(60秒)

      # MySQL特定配置
      data-source-properties:
        cachePrepStmts: true
        prepStmtCacheSize: 250
        prepStmtCacheSqlLimit: 2048
        useServerPrepStmts: true
        useLocalSessionState: true
        rewriteBatchedStatements: true
        cacheResultSetMetadata: true
        cacheServerConfiguration: true
        elideSetAutoCommits: true
        maintainTimeStats: false

5.2 连接池大小公式
Tomcat JDBC / HikariCP 通用公式:
image.png
实际建议:

单机部署:最大连接数 = CPU核心数 × 2

微服务场景:单个服务连接数不宜超过50

// 动态调整连接池(根据负载)
@Component
public class DynamicDataSourceConfig {

    @EventListener
    public void handleSlowQuery(SlowQueryEvent event) {
        HikariPoolMXBean poolMXBean = getPoolMXBean();
        int activeConnections = poolMXBean.getActiveConnections();
        int maxConnections = poolMXBean.getMaximumPoolSize();

        if (activeConnections > maxConnections * 0.8) {
            // 连接使用率超过80%,扩容
            poolMXBean.setMaximumPoolSize(maxConnections + 5);
            log.warn("连接池扩容至: {}", maxConnections + 5);
        }
    }
}

5.3 连接泄漏检测

// 配置泄漏检测(生产环境建议开启)
@Configuration
public class DataSourceConfig {

    @Bean
    public DataSource dataSource() {
        HikariConfig config = new HikariConfig();
        config.setLeakDetectionThreshold(30000);  // 30秒未归还即告警
        config.setConnectionTimeout(30000);
        return new HikariDataSource(config);
    }
}

// 监控连接状态
@Scheduled(fixedDelay = 60000)
public void monitorConnections() {
    HikariPoolMXBean poolMXBean = getPoolMXBean();
    logger.info("连接池状态: 活跃={}, 空闲={}, 总数={}, 等待线程={}",
        poolMXBean.getActiveConnections(),
        poolMXBean.getIdleConnections(),
        poolMXBean.getTotalConnections(),
        poolMXBean.getThreadsAwaitingConnection());
}

六、事务隔离级别与锁机制

6.1 四种隔离级别对比
image.png
6.2 MVCC原理(多版本并发控制)

-- InnoDB每行数据隐藏列:
-- DB_TRX_ID: 最后修改的事务ID
-- DB_ROLL_PTR: 回滚指针(指向undo log)
-- DB_ROW_ID: 行ID(聚簇索引无此列)

-- READ COMMITTED下:每次查询生成新的ReadView
-- REPEATABLE READ下:事务内第一次查询生成ReadView,后续复用

-- 查看当前事务ID
SELECT TRX_ID FROM information_schema.innodb_trx WHERE TRX_MYSQL_THREAD_ID = CONNECTION_ID();

6.3 锁的类型与使用场景

-- 行锁(InnoDB默认)
-- 注意:只有通过索引查询才会使用行锁,否则升级为表锁

-- 共享锁(S锁):允许其他事务读,不允许写
SELECT * FROM orders WHERE id = 1 LOCK IN SHARE MODE;
-- 排他锁(X锁):不允许其他事务读和写
SELECT * FROM orders WHERE id = 1 FOR UPDATE;

-- 间隙锁(Gap Lock):锁定范围,防止幻读(仅在REPEATABLE READ级别)
-- 假设orders表id有1,2,5,10
SELECT * FROM orders WHERE id BETWEEN 3 AND 7 FOR UPDATE;
-- 锁定范围:(2,5)、(5,10)

-- 临键锁(Next-Key Lock)= 行锁 + 间隙锁

-- 死锁示例与排查
-- 事务A:
BEGIN;
UPDATE orders SET status = 1 WHERE id = 1;
UPDATE orders SET status = 2 WHERE id = 2;
COMMIT;

-- 事务B:
BEGIN;
UPDATE orders SET status = 3 WHERE id = 2;
UPDATE orders SET status = 4 WHERE id = 1;
COMMIT;
-- 可能死锁

-- 查看死锁信息
SHOW ENGINE INNODB STATUS\G
-- 死锁日志位置:/var/log/mysql/error.log

-- 避免死锁策略:
-- 1. 固定访问顺序(按主键排序)
-- 2. 缩短事务时间
-- 3. 使用低隔离级别
-- 4. 添加合适的索引

6.4 事务最佳实践

@Service
@Transactional(rollbackFor = Exception.class)
public class OrderService {

    // 正确做法:事务边界清晰,粒度适中
    public void createOrder(OrderDTO dto) {
        // 1. 校验(非数据库操作,放在事务外)
        validateOrder(dto);

        // 2. 核心业务(事务内)
        Order order = new Order();
        order.setUserId(dto.getUserId());
        order.setAmount(dto.getAmount());
        orderMapper.insert(order);

        // 3. 扣库存(分布式事务场景考虑最终一致性)
        inventoryService.decreaseStock(dto.getProductId(), dto.getQuantity());

        // 4. 发送消息(事务内无法保证消息可靠,使用事务消息)
        eventPublisher.publish(new OrderCreatedEvent(order.getId()));
    }

    // 错误做法1:事务过大(包含RPC、文件操作)
    @Transactional
    public void badMethod() {
        orderMapper.insert(order);
        restTemplate.postForObject("http://payment/pay", order, Void.class);  // RPC
        fileService.writeToFile(order);  // 文件IO
        // 问题:事务期间持有数据库连接,RPC/IO阻塞会导致连接长时间占用
    }

    // 错误做法2:捕获异常不抛出
    @Transactional
    public void badMethod2() {
        try {
            orderMapper.insert(order);
            int i = 1 / 0;  // 抛出异常
        } catch (Exception e) {
            // 捕获后不抛出,事务不会回滚!
            log.error("error", e);
        }
    }

    // 错误做法3:事务传播级别使用不当
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void createLog(Log log) {
        // 独立事务,不受外层事务影响
        logMapper.insert(log);
    }
}

6.5 事务传播级别详解
image.png

// NESTED的使用场景:部分回滚
@Transactional
public void parentMethod() {
    orderMapper.insert(order1);
    try {
        childMethod();  // 失败只回滚childMethod内的操作
    } catch (Exception e) {
        // childMethod已回滚,parentMethod继续
    }
    orderMapper.insert(order2);
}

@Transactional(propagation = Propagation.NESTED)
public void childMethod() {
    // 嵌套事务,内部失败只回滚到保存点
}

来源:
http://hllft.cn/

相关文章
|
9天前
|
Shell API 开发工具
Claude Code 快速上手指南(新手友好版)
AI编程工具卷疯啦!Claude Code凭借任务驱动+终端原生的特性,成了开发者的效率搭子。本文从安装、登录、切换国产模型到常用命令,手把手带新手快速上手,全程避坑,30分钟独立用起来。
2794 16
|
6天前
|
人工智能 开发工具 iOS开发
Claude Code 新手完全上手指南:安装、国产模型配置与常用命令全解
Claude Code 是一款运行在终端环境中的 AI 编程助手,能够直接在命令行中完成代码生成、项目分析、文件修改、命令执行、Git 管理等开发全流程工作。它最大的特点是**任务驱动、终端原生、轻量高效、多模型兼容**,无需图形界面、不依赖 IDE 插件,能够深度融入开发者日常工作流。
2383 5
|
21天前
|
人工智能 JSON 供应链
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
LucianaiB分享零成本畅用JVS Claw教程(学生认证享7个月使用权),并开源GeoMind项目——将JVS改造为科研与产业地理情报可视化AI助手,支持飞书文档解析、地理编码与腾讯地图可视化,助力产业关系图谱构建。
23554 14
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
|
8天前
|
人工智能 JSON BI
DeepSeek V4-Pro 接入 Claude Code 完全实战:体验、测试与关键避坑指南
Claude Code 作为当前主流的 AI 编程辅助工具,凭借强大的代码理解、工程执行与自动化能力深受开发者喜爱,但原生模型的使用成本相对较高。为了在保持能力的同时进一步降低开销,不少开发者开始寻找兼容度高、价格更友好的替代模型。DeepSeek V4 系列的发布带来了新的选择,该系列包含 V4-Pro 与 V4-Flash 两款模型,并提供了与 Anthropic 完全兼容的 API 接口,理论上只需简单修改配置,即可让 Claude Code 无缝切换为 DeepSeek 引擎。
2086 2
|
2天前
|
人工智能 Linux BI
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
JeecgBoot AI专题研究 一键脚本:Claude Code + JeecgBoot Skills + DeepSeek 全平台接入 一行命令装好 Claude Code + JeecgBoot Skills + DeepSeek 接入,无需翻墙使用 Claude Code,支持 Wind
1362 1
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
|
15天前
|
人工智能 缓存 Shell
Claude Code 全攻略:命令大全 + 实战工作流(完整版)
Claude Code 是一款运行在终端环境下的 AI 编码助手,能够直接在项目目录中理解代码结构、编辑文件、执行命令、执行开发计划,并支持持久化记忆、上下文压缩、后台任务、多模型切换等专业能力。对于日常开发、项目维护、快速重构、代码审查等场景,它可以大幅减少手动操作、提升编码效率。本文从常用命令、界面模式、核心指令、记忆机制、图片处理、进阶工作流等维度完整说明,帮助开发者快速上手并稳定使用。
3483 6
|
7天前
|
人工智能 安全 开发工具
Claude Code 官方工作原理与使用指南
Claude Code 不是传统代码补全工具,而是 Anthropic 推出的终端 AI 代理,具备代理循环、双驱动架构(模型+工具)、全局项目感知、6 种权限模式等核心能力,本文基于官方文档系统解析其工作原理与高效使用技巧。
1113 0