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

简介: 教程来源 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/

相关文章
|
20天前
|
人工智能 自然语言处理 数据可视化
【AI 尝鲜实验室】5.22 号上新 | DeepSeek-TUI:终端里 DeepSeek 版的 Claude Code
本实验通过阿里云计算巢快速部署DeepSeek-TUI,配置API Key后即可在云服务器终端中使用命令行与AI编程助手交互,支持代码生成、脚本处理、项目搭建及问题排查等开发任务,全程可视化、低门槛、高效率。
988 25
|
21天前
|
人工智能 API 开发者
阿里云发布为Agent而生的全新AI产品官网“千问云”,模型服务全面Skill、CLI化
5月20日,阿里云发布“千问云”(www.qianwenai.com)——专为Agent时代打造的AI模型服务平台,集成150+主流模型API,首创Skills与CLI工具链,支持模型选型、调用、用量管理等全链路自动化,助力开发者与Agent高效构建AI应用。
1246 32
|
Java Maven
maven依赖原则以及jar包冲突
该文介绍了Maven依赖原则:最短路径优先,申明顺序优先和覆写优先。当有冲突时,Maven选择路径最短的版本,按POM中声明顺序加载,并且子POM的依赖优先于父POM。解决冲突最佳方式是通过`mvn dependency:tree`检查依赖树并调整POM文件中的坐标顺序。
568 2
|
Java Maven
【异常解决】为什么会产生jar包冲突,如何排查jar包冲突?
【异常解决】为什么会产生jar包冲突,如何排查jar包冲突?
964 0
|
3月前
|
编解码 关系型数据库 Java
阿里云服务器4核8G最低价格:通用算力型、经济型、计算型等不同实例活动价格参考
阿里云4核8G云服务器是企业级应用、高流量网站及复杂开发测试环境的优选配置。本文解析了通用算力型u2a实例、通用算力型u2i实例、经济型e实例、计算型c9i实例四款主流产品,它们最低活动价分别为898.20元/年、1252.63元/年、1595.11元/年、3147.56元/年起。各实例在性能、架构及适用场景上各有侧重,用户可根据需求与预算选择,并建议购买前领取优惠券以获取额外减免。
|
20天前
|
消息中间件 负载均衡 算法
程序员必备的十大技能(进阶版)之分布式核心技术(一)
教程来源 http://unbgv.cn/ 本文系统剖析分布式核心技术,涵盖CAP/BASE理论、服务治理、一致性协议、分布式事务、锁、消息中间件、负载均衡、存储及可观测性九大维度,直击微服务演进中的核心挑战与落地实践。
|
20天前
|
消息中间件 缓存 供应链
Java在供应链管理系统(SCM)中的深度应用
供应链管理系统涵盖采购、生产、库存、仓储、运输、分销等环节。SCM的核心挑战:
79 0
|
20天前
|
存储 缓存 负载均衡
程序员必备的十大技能(进阶版)之分布式核心技术(五)
教程来源 http://yvyus.cn/ 本节系统讲解分布式核心能力:涵盖加权随机、最少活跃连接等负载均衡算法;Failover、Forking等容错策略;多级缓存与一致性保障;虚拟桶分片与平滑迁移;OpenTelemetry链路追踪及全链路日志透传,助力构建高可用、可观测的分布式系统。
|
20天前
|
消息中间件 程序员 RocketMQ
程序员必备的十大技能(进阶版)之分布式核心技术(三)
教程来源 http://vbzcj.cn/ 分布式事务三大主流方案:2PC(强一致、同步阻塞)、TCC(业务侵入、高灵活)、RocketMQ事务消息(最终一致、异步解耦),分别适用于金融核心、高并发微服务及积分订单等场景。
|
20天前
|
SQL 缓存 监控
程序员必备的十大技能(进阶版)之高性能数据库实战(五)
教程来源 http://qcycj.cn/ 本节涵盖数据库监控诊断(慢日志配置、实时SQL与表状态分析)、NoSQL/NewSQL选型策略(缓存穿透/击穿/雪崩应对、分库分表与TiDB对比),以及千万级订单系统的实战优化路径,强调“硬件→架构→业务”逐层治理理念。