java中数据库死锁发生时jdbc驱动抛出sqlexception而非databasedeadlockexception,需通过sqlstate或错误码识别死锁(如mysql的1213、postgresql的40p01等),再封装为继承runtimeexception的自定义异常,并借助spring sqlexceptiontranslator统一转译。

Java中数据库死锁发生时,JDBC驱动通常不会直接抛出 DatabaseDeadlockException(该类并不存在于标准JDK或主流ORM框架中),而是抛出特定数据库厂商的SQL异常(如 SQLException),其错误码(SQLState 或 vendorCode)表明发生了死锁。要将其“转译”为自定义的 DatabaseDeadlockException,需在数据访问层捕获原始异常,根据错误特征识别死锁,并手动封装为业务语义更明确的异常。
识别死锁的关键异常特征
不同数据库的死锁标识方式不同,需依据实际使用的数据库类型判断:
-
MySQL:常见 SQLState 为
40001(SERIALIZABLE 冲突)或1213错误码(Deadlock found when trying to get lock) - PostgreSQL:SQLState =
40P01(deadlock_detected) -
Oracle:SQLState =
61000或错误消息含ORA-00060(deadlock detected while waiting for resource) -
SQL Server:错误号 =
1205(deadlock victim)
定义自定义 DatabaseDeadlockException
建议继承 RuntimeException(无需强制捕获),保留原始异常上下文:
Java Linux版下载入口,提供 Oracle JDK 26.0.2 官方 Linux 安装包、Java 环境配置、JDBC 数据库连接和 Java 服务端开发相关信息。
public class DatabaseDeadlockException extends RuntimeException {
public DatabaseDeadlockException(String message, Throwable cause) {
super(message, cause);
}
}
在DAO或Repository中做异常转译
以 Spring JDBC 或 MyBatis 为例,在执行 SQL 后捕获 SQLException,检查是否为死锁,再抛出自定义异常:
- 使用
SQLException.getSQLState()或getErrorCode()判断 - 避免仅依赖消息文本(易受本地化影响),优先用错误码/SQLState
- 若使用 Spring,可配合
@Repository+SQLExceptionTranslator实现统一转换
借助Spring的异常翻译机制(推荐)
Spring JDBC 提供了 SQLExceptionTranslator,可通过扩展 SQLStateSQLExceptionTranslator 或 CustomSQLExceptionTranslator 实现自动转译:
- 重写
translate()方法,对已知死锁码返回new DatabaseDeadlockException(...) - 配置
JdbcTemplate或DataSourceTransactionManager使用该 translator - 这样所有 DAO 层抛出的
DataAccessException都能统一处理,上层只需捕获DatabaseDeadlockException
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










