应通过SQLException的getErrorCode()和getSQLState()精准识别数据库错误类型:SQLState前两位(如08、23)用于通用分类处理,errorCode补充厂商特异性判断,需遍历异常链并校验空值。

捕获并处理 SQLException 中的错误码(errorCode)和 SQL 状态码(SQLState),是精准识别数据库问题类型、实现差异化响应的关键。不能只靠 getMessage() 做泛化处理,而应结合这两个字段做结构化判断。
获取 errorCode 和 SQLState 的基本方式
这两个值通过异常对象直接获取,无需额外解析:
-
e.getErrorCode():返回数据库厂商定义的整数错误码,如 MySQL 的1062(重复键)、PostgreSQL 的23505(唯一约束违规) -
e.getSQLState():返回符合 SQL 标准的 5 位字符串,格式为XXYYY,前两位代表大类(如08表示连接异常,23表示完整性约束违规)
按 SQLState 前缀分类处理常见场景
SQLState 的前两位具有通用语义,适合做策略分发:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
"08"(连接类):如"08001"(无法连接)、"08S01"(通信链路中断)→ 可触发重试或降级 -
"23"(数据完整性):如"23000"(通用约束违例)、"23505"(PostgreSQL 主键/唯一冲突)→ 转业务提示,不回滚整个事务 -
"42"(语法/对象类):如"42S02"(表不存在)、"42703"(列不存在)→ 属于开发配置错误,应记录并告警,不向用户暴露 -
"57"(系统类):如"57014"(查询超时)→ 区分是否可重试,避免误判为失败
结合 errorCode 做数据库特异性判断
当 SQLState 不够细粒度时,用 errorCode 补充识别:
立即学习“Java免费学习笔记(深入)”;
- MySQL 插入重复主键 →
SQLState = "23000",errorCode = 1062 - MySQL 连接拒绝 →
SQLState = "08001",errorCode = 1042 - Oracle 用户权限不足 →
SQLState = "28000",errorCode = 1017 - 代码中可用 switch 或 map 映射 errorCode 到具体业务含义,例如:
if (e.getSQLState().startsWith("23") && e.getErrorCode() == 1062) { /* 处理 MySQL 重复键 */ }
注意异常链与空值安全
批量操作或连接池异常可能产生嵌套异常:
- 调用
e.getNextException()遍历完整异常链,避免遗漏子错误 - HikariCP 等连接池抛出的底层异常,
getSQLState()可能为null,需先判空再使用 - 不要仅依赖
instanceof SQLException,要确认实例非 null 且字段可读


















