如何捕获断开的数据库连接

How to catch a broken database connection

我正在开发一个应用程序,它使用 Spring JDBC 模板从数据库中检索信息并将信息输入到数据库中。在服务层,我想设置一些逻辑来在数据库出现故障时捕获异常。但是,我不知道该怎么做。我可以设置方法以在它们失败时进行捕获,但我想为服务器关闭设置特定的逻辑。

作为一个选项 - 您可以创建一个调度程序来检查数据库连接。

可以通过执行简单查询或通过 Connection 界面检查数据库连接:

boolean isValid(int timeout) throws SQLException

Returns true if the connection has not been closed and is still valid. The driver shall submit a query on the connection or use some other mechanism that positively verifies the connection is still valid when this method is called. The query submitted by the driver to validate the connection shall be executed in the context of the current transaction.

通过 Spring 调度程序检查数据库连接的示例:

@Service
public class ConnectionListener {

    private Connection connection;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @PostConstruct
    public void init() {
         connection = jdbcTemplate.getDatasource().getConnection();
    }

    @Scheduled(fixedRate = 60000) // check every 60 sec
    public void checkConnection() {
        try {
            connection.isValid(10);
        } catch (SQLException e) { // Or just handle it here
            throw new ConnectionTimeoutException(e);
        }
    }
}

您需要一些额外的配置来处理从 Spring 调度程序抛出的异常:

@EnableScheduling
@Configuration
class SchedulingConfiguration implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(...);
    }
}

调度器也可以用ExecutorService实现。

@Service
class ConnectionLisener {

    private ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
    private Connection connection;

    @PostConstruct
    public void init() {
        connection = jdbcTemplate.getDatasource().getConnection();
        checkConnection();
    }

    @PreDestroy
    public void destroy() {
        service.shutdown();
    }

    public void checkConnection() {
        service.scheduleAtFixedRate(() -> {
            try {
                connection.isValid(10);
            } catch (Exception e) { 
                // handle your exception
            }
        }, 60, 60, TimeUnit.SECONDS);
    }
}

这是一个总体概述,只是一些进一步研究的提示。

请注意,如果服务器出现故障,您需要进行灾难恢复,捕获异常将无济于事。这是一项庞大的基础架构和架构任务,而不是单个应用程序的责任。