如何为 Spring Datasource 创建自定义重试逻辑?

2024-05-04

我正在连接到 Azure SQL 数据库,下一个任务是在连接失败时创建自定义重试逻辑。我希望重试逻辑在启动时(如果需要)以及应用程序运行时出现连接失败时运行。我做了一个测试,从我的应用程序中删除了 IP 限制,然后导致我的应用程序出现异常(如例外)。我想在抛出该异常时进行处理,以便我可以触发一个作业来验证应用程序和服务器是否配置正确。我正在寻找一种可以处理这些异常并重试数据库事务的解决方案?

数据源配置

@Bean
@Primary
public DataSource dataSource() { 
     return DataSourceBuilder
            .create()
            .username("username")
            .password("password")
            .url("jdbc:sqlserver://contoso.database.windows.net:1433;database=*********;user=******@*******;password=*****;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;")
            .driverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver")
            .build();
}

应用程序属性

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServerDialect
spring.jpa.show-sql=true
logging.level.org.springframework.web: ERROR
logging.level.org.hibernate: ERROR
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=1
spring.datasource.tomcat.test-on-borrow=true
spring.jpa.hibernate.ddl-auto=update

Answer recommended by Microsoft Azure /collectives/azure Collective

以下代码可以帮助您为 Spring Boot 上的数据源创建重试逻辑:

package com.example.demo;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.jdbc.datasource.AbstractDataSource;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Retryable;

@SpringBootApplication
@EnableRetry
public class DemoApplication {

    @Order(Ordered.HIGHEST_PRECEDENCE)
    private class RetryableDataSourceBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
                throws BeansException {
            if (bean instanceof DataSource) {
                bean = new RetryableDataSource((DataSource)bean);
            }
            return bean;
        }

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName)
                throws BeansException {
            return bean;
        }
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean
    public BeanPostProcessor dataSouceWrapper() {
        return new RetryableDataSourceBeanPostProcessor();
    }
}

class RetryableDataSource extends AbstractDataSource {

    private DataSource delegate;

    public RetryableDataSource(DataSource delegate) {
        this.delegate = delegate;
    }

    @Override
    @Retryable(maxAttempts=10, backoff=@Backoff(multiplier=2.3, maxDelay=30000))
    public Connection getConnection() throws SQLException {
        return delegate.getConnection();
    }

    @Override
    @Retryable(maxAttempts=10, backoff=@Backoff(multiplier=2.3, maxDelay=30000))
    public Connection getConnection(String username, String password)
            throws SQLException {
        return delegate.getConnection(username, password);
    }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何为 Spring Datasource 创建自定义重试逻辑? 的相关文章

随机推荐

  • 使用 MVVM 的 C# 泛型,将 T 从 中取出

    My Model是一个泛型类 包含 例如 Value属性可以是 int float string bool 等 所以很自然地 这个类的表示形式如下Model
  • jQuery:移动窗口视口以显示新切换的元素

    我在文档中有一段 jQuery 代码片段 它可以切换包含 a 的 divtextarea div addnote area hide hide the div a addnote link click function click even
  • Storm动态拓扑

    Storm 支持动态拓扑吗 我想要的功能是在 Storm 拓扑运行时根据用户要求动态更改拓扑 例如 当用户想知道流的前 10 个单词时 我使用前 10 个 Bolt 来处理它 当用户想知道其他内容时 我使用另一个 Bolt 来处理流并 拔掉
  • 使用 jQuery 选择特定 href 的锚标记

    THE AIM 刷新浏览器后 我希望用户保留在刷新之前的菜单 内容中 问题 刷新浏览器后 用户刷新之前所在的特定菜单的内容将显示为活动状态 即显示在屏幕上 但是 该特定内容的菜单图标未显示为活动状态 即 它不显示黑色 我在选择锚元素时遇到困
  • Visual C# 窗体中的控制台

    我想在我的表单中获得一个控制台窗口 基本上当你点击button1 它运行一个批处理脚本 test exe 我不需要单独的批处理窗口 但我希望它显示在我的表单中 我认为可能有两种方法可以做到这一点 要么 1 以某种方式将控制台嵌入到我的表单中
  • PowerShell 中一个命令中的多个前景色

    我想用一个语句输出许多不同的前景色 PS C gt Write Host Red ForegroundColor Red Red 该输出为红色 PS C gt Write Host Blue ForegroundColor Blue Blu
  • 如何关闭使用presentModalViewController打开的视图控制器:

    我使用了一个视图控制器presentModalViewController 现在如何关闭 关闭它 对于 iOS6 使用此代码 self dismissViewControllerAnimated YES completion Nil 代替
  • 我怎样才能重写这个nginx“if”语句?

    例如 我想这样做 if http user agent MSIE 6 0 http user agent MSIE 7 0 etc etc rewrite ROOT ROOT ancient last break 而不是这个 if http
  • document.all 和 document.forms 之间的区别[0]

    任何人都可以解释一下两者之间有什么区别 document all 和document forms 0 please 谢谢 document all为您提供对包含文档所有元素的类数组对象的引用在 Internet Explorer 中 IE
  • 是否可以在切换 QTreeWidgetItem 复选框时创建信号?

    我使用下面的代码创建了一个也是 QTreeWidgetItem 的复选框 Populate list QTreeWidgetItem program createCheckedTreeItem QString fromStdString i
  • Google Cloud ML:输出的外部尺寸必须未知

    我们在本地得到了一个工作的导出模型 正在创建一个新的模型版本谷歌云机器学习如下 Create Version failed Model validation failed Outer dimension for outputs must b
  • JobService 在 android 9 中不会重新安排

    我正在尝试让我的应用程序在 Android 9 上运行 以下代码在 Android 8 上运行良好 但由于某种原因 JobService 不会在 android 9 上重新安排 它第一次被安排 但不会根据到设定的周期 class Retri
  • 如果为 null 则替换为 0,否则在同一列中使用默认值

    在SparkR shell 1 5 0中 创建了一个示例数据集 df test lt createDataFrame sqlContext data frame mon c 1 2 3 4 5 year c 2011 2012 2013 2
  • 使图例填满字段集中的整个宽度

    我想要一个背景legend场内的一个fieldset 我希望它占据整个宽度 但仅限于字段集中 如果我使用legend width 100 这将是wider比fieldset 这是一个例子 可以运行在JSFiddle http jsfiddl
  • AWS EMR PySpark 连接到 mysql

    我正在尝试使用 jdbc 通过 pyspark 连接到 mysql 我可以在 EMR 之外完成此操作 但是当我尝试使用 EMR 时 pyspark 无法正确启动 我在我的机器上使用的命令 pyspark conf spark executo
  • Python matplotlib:数据坐标中的位置颜色条

    我想通过指定数据坐标中的位置来将颜色条放置在散点图中 以下是指定图形坐标时它如何工作的示例 import numpy as np import matplotlib pyplot as plt Generate some random da
  • reindex 目录 URL 在 magento 中重写永无止境

    我已使用自定义导入配置文件将 6K 类别和 16K 产品导入到 magento 当我尝试重新索引时 除了 目录 URL 重写 之外的所有内容都正常工作 该 目录 URL 重写 一直显示 正在处理 但从未完成 日志和异常文件不显示任何内容 我
  • 命名 Python 记录器

    在 Django 中 我到处都有记录器 目前具有硬编码名称 对于模块级日志记录 即在视图函数的模块中 我有这样做的冲动 log logging getLogger name 对于类级别的日志记录 即在类中 init 方法 我有这样做的冲动
  • Kotlin 中是否可以为 mutableStateOf() 提供自定义设置器

    我想在每次设置某个状态后两秒进行一些操作 viewModel 内的代码 var isLoading mutableStateOf LoadingState NONE set value Timber d Custom Setter Not
  • 如何为 Spring Datasource 创建自定义重试逻辑?

    我正在连接到 Azure SQL 数据库 下一个任务是在连接失败时创建自定义重试逻辑 我希望重试逻辑在启动时 如果需要 以及应用程序运行时出现连接失败时运行 我做了一个测试 从我的应用程序中删除了 IP 限制 然后导致我的应用程序出现异常