You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot使用JdbcTemplate如何捕获SQLRecoverableException异常

JdbcTemplate 不会直接抛出原生JDBC异常,所有数据库操作异常都会被包装为Spring的 DataAccessException 子类,原生的java.sql.SQLRecoverableException会作为异常cause嵌套在包装异常中,因此直接在catch块声明捕获SQLRecoverableException无法命中。

具体实现方案

方案1:单方法内针对性捕获处理

直接在现有方法的catch块中遍历异常cause链,匹配目标异常后执行专属逻辑,修改后的代码示例:

首先引入需要的类:

import org.springframework.dao.DataAccessException;
import java.sql.SQLRecoverableException;
import java.util.Collections;

方法实现:

@Override
public List<Invoice> getByDate(String date_debut, String date_fin) {
    try {
        return jdbcTemplate.query(GET_BY_DATE, (rs, rowNum) -> new Invoice(
                rs.getString("CUST_CODE"),
                rs.getString("CUST_NAME"),
                rs.getString("CUST_ADDR1")
        ), date_debut, date_fin);
    } catch (DataAccessException e) {
        Throwable currentEx = e;
        boolean isRecoverableConnError = false;
        // 遍历异常链查找目标异常
        while (currentEx != null) {
            if (currentEx instanceof SQLRecoverableException) {
                isRecoverableConnError = true;
                break;
            }
            currentEx = currentEx.getCause();
        }

        if (isRecoverableConnError) {
            // 此处编写SQLRecoverableException专属处理逻辑:例如连接失败告警、有限次数重试、返回降级结果
            System.out.println("数据库连接异常(可恢复),执行针对性处理");
            return Collections.emptyList();
        }

        // 其他数据库异常通用处理逻辑
        System.out.println("捕获到其他数据库操作异常");
        return null;
    }
}

方案2:抽离公共判断逻辑(多方法复用场景)

如果项目中多个数据库操作方法都需要识别该异常,把异常链遍历逻辑抽为公共工具方法,避免重复编码:

/**
 * 检查异常链中是否包含指定类型的异常
 * @param ex 捕获到的原始异常
 * @param targetExClass 需要匹配的异常类型
 * @return 存在匹配异常返回true,否则返回false
 */
public static boolean containSpecifiedException(Throwable ex, Class<? extends Throwable> targetExClass) {
    Throwable current = ex;
    while (current != null) {
        if (targetExClass.isInstance(current)) {
            return true;
        }
        current = current.getCause();
    }
    return false;
}

业务代码中直接调用即可:

catch (DataAccessException e) {
    if (containSpecifiedException(e, SQLRecoverableException.class)) {
        // 专属处理逻辑
    }
    // 其他异常处理
}
注意事项
  • 不要直接声明catch (SQLRecoverableException e),由于异常被Spring包装,该catch块永远不会命中。
  • SQLRecoverableException代表网络闪断、数据库瞬时不可达这类可恢复故障,做针对性处理时可以搭配有限次重试机制,重试需要设置合理间隔,避免瞬间大量请求压垮刚恢复的数据库。
  • 不要吞异常,处理时建议记录完整错误栈和请求参数,生产环境不要依赖System.out打印日志,使用SLF4J等日志框架输出。

内容的提问来源于stack exchange,提问作者Veron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 23:21:32