应优先使用datasource(如hikaricp、druid)替代drivermanager,因其支持连接池、自动重连、监控及配置隔离;jdbc默认auto-commit=true,需手动setautocommit(false)控制事务边界;spring @transactional仅对public方法生效,且默认仅对runtimeexception回滚。

数据库连接:从 DriverManager 到 DataSource
Java 中获取数据库连接最基础的方式是 DriverManager.getConnection(),但实际项目中应优先使用 DataSource(如 HikariCP、Druid)。它支持连接池、自动重连、监控和配置隔离,避免每次请求都新建物理连接。
关键点:
- 不要在代码里硬编码 URL、用户名、密码;通过配置文件(application.yml 或 properties)注入
- HikariCP 推荐配置:maximumPoolSize=20、connectionTimeout=3000、idleTimeout=600000
- 用 try-with-resources 确保 Connection/Statement/ResultSet 及时关闭(即使发生异常)
JDBC 事务:手动控制的核心逻辑
JDBC 默认开启自动提交(auto-commit=true),即每条 SQL 执行后立即生效。要实现多语句原子性,必须显式关闭自动提交,并手动管理 commit/rollback。
典型流程:
- conn.setAutoCommit(false) —— 开启事务边界
- 执行 insert/update/delete 操作
- 无异常则 conn.commit(),否则 conn.rollback()
- 无论成功失败,最后都要 conn.setAutoCommit(true) 恢复默认(尤其在连接池场景下)
注意:rollback 不会释放锁或关闭连接,只回滚未提交的变更。
Spring 中的声明式事务:@Transactional 的实用要点
Spring 的 @Transactional 是最常用的事务抽象,但它不是“魔法”,依赖 AOP 代理和事务管理器(PlatformTransactionManager)。
常见陷阱与建议:
- 仅对 public 方法 生效;private/protected 方法加注解无效
- 同一类中方法自调用(A 调 B,B 有 @Transactional)不会触发事务代理 —— 需拆分到不同 Bean 或用 TransactionTemplate
- 默认只对 RuntimeException 及其子类 回滚;如需检查异常也回滚,加 rollbackFor = Exception.class
- 传播行为选 REQUIRED(默认)适用于大多数场景;嵌套调用需谨慎用 REQUIRES_NEW(可能破坏一致性)
连接泄漏与事务悬挂:必须排查的隐蔽问题
连接未关闭、事务未提交/回滚,会导致连接池耗尽或数据库锁表,线上故障高频原因。
自查方向:
- 启用 HikariCP 的 leakDetectionThreshold=60000(毫秒),超时未归还连接会打印堆栈
- 开启 Spring 的 transaction.debug=true,查看事务创建/绑定/提交日志
- 数据库侧查长事务:SELECT * FROM information_schema.INNODB_TRX(MySQL)
- 确保所有数据访问层(DAO/Repository)不持有 Connection 引用,交给框架统一管理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











