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

如何在Spring Boot应用中为API设置超时并关闭数据库连接?

解决Spring Boot API超时30秒关闭数据库连接并返回错误的方案

你提到的两个配置之所以无效,是因为它们的作用场景和你要解决的问题不匹配:

  • server.tomcat.connection-timeout:控制Tomcat服务器接受客户端连接的超时时间,并非API业务处理的超时。
  • spring.mvc.async.request-timeout:仅对异步请求(比如返回Callable、DeferredResult的接口)生效,同步接口不会触发该超时。

下面是几个可行的解决方案,从API层面到数据库层面全覆盖:

1. 同步接口全局超时控制(AOP实现)

通过AOP环绕通知,给所有API方法设置超时时间,超时后中断线程并关闭数据库连接:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@Aspect
@Component
public class ApiTimeoutAspect {
    private final ExecutorService executor = Executors.newCachedThreadPool();

    @Around("execution(* com.yourpackage.controller..*(..))")
    public Object handleApiTimeout(ProceedingJoinPoint joinPoint) throws Throwable {
        try {
            // 设置30秒超时
            return executor.submit(joinPoint::proceed).get(30, TimeUnit.SECONDS);
        } catch (TimeoutException e) {
            // 中断当前线程,触发数据库连接的中断逻辑
            Thread.currentThread().interrupt();
            // 手动关闭当前请求关联的数据库连接(示例,根据你的数据源实现调整)
            // Connection conn = ...;
            // if (conn != null && !conn.isClosed()) {
            //     conn.close();
            // }
            throw new RuntimeException("请求超时,请稍后重试");
        }
    }
}

2. 数据库层面强制超时

即使API层面的超时触发,数据库查询也可能仍在执行,因此必须在数据库层设置查询超时,避免连接资源浪费:

针对HikariCP数据源(Spring Boot默认)

在application.yml中添加:

spring:
  datasource:
    hikari:
      connection-timeout: 30000 # 获取连接的超时时间
      idle-timeout: 600000 # 连接空闲超时
      max-lifetime: 1800000 # 连接最大存活时间
      # MySQL额外添加socket超时参数
      jdbc-url: jdbc:mysql://localhost:3306/db?connectTimeout=30000&socketTimeout=30000

针对MyBatis

在Mapper接口方法上添加超时配置:

@Options(timeout = 30000)
@Select("SELECT * FROM your_table WHERE id = #{id}")
YourEntity getById(Long id);

针对JPA

在application.yml中添加全局查询超时:

spring:
  jpa:
    properties:
      javax.persistence.query.timeout: 30000

3. 全局异常处理返回统一错误

用@ControllerAdvice捕获超时相关异常,返回友好的错误响应:

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler({RuntimeException.class, TimeoutException.class})
    @ResponseBody
    public Map<String, Object> handleTimeoutException(Exception e) {
        Map<String, Object> result = new HashMap<>();
        result.put("code", 504);
        result.put("message", "请求超时,请稍后重试");
        result.put("detail", e.getMessage());
        return result;
    }
}

4. 异步接口超时优化(若接口为异步实现)

如果部分接口是异步实现,确保spring.mvc.async.request-timeout配置正确,同时结合异步线程池的超时设置:

spring:
  mvc:
    async:
      request-timeout: 30000

自定义异步线程池并设置超时:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;

@Configuration
public class AsyncConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(20);
        executor.setThreadNamePrefix("Async-");
        executor.setAwaitTerminationSeconds(30);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.initialize();
        return executor;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 06:55:25