当前位置: 首页 > 知识库问答 >
问题:

如何为Spring数据源创建自定义重试逻辑?

庞修贤
2023-03-14

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

数据源配置

@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

共有2个答案

王凌
2023-03-14

不确定您认为什么是定制的,但是通过利用pom,Spring boot和Aspectj有一个现成的选项。mavern项目中的xml,因为spring重试取决于Aspectj:

在项目pom中添加以下依赖项。xml:

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>${version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>${version}</version>
</dependency>
苏宾鸿
2023-03-14

以下代码可以帮助您在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);
    }

}
 类似资料:
  • 问题内容: 我正在使用REST服务(使用Spring引导),该服务运行批处理作业。我希望Batch仅与嵌入式数据源(用于存储元数据)一起使用,而默认数据源(在我的情况下为Postgres)将用于存储企业实体。 问题在于,Batch会在启动时尝试在默认数据源中创建元数据表(如 batch_job_execution , batch_job_instance 等)。 这是重现问题的示例配置: 批处理配

  • 我正在使用运行批处理作业的REST-service(使用Spring Boot)。我希望Batch仅适用于嵌入式数据源(存储元数据),而默认数据源(在我的例子中为Postgres)将用于存储业务实体。 问题是Batch试图在启动时在默认数据源中创建元数据表(如batch_job_execution、batch_job_instance等)。 以下是重现问题的示例配置: 批量配置 数据源配置 通过这

  • 问题内容: 我正在http://www.cafeaulait.org/javafaq.html上阅读#6.10项,然后我开始怀疑大型企业如何创建自己的JVM实现。一个人会尝试(或可行)实验性的东西吗? 问题答案: 从技术上讲,创建该新JVM所需的所有信息都是该语言和目标平台的公共规范。即使字节码解释在很大程度上相同,JVM还是需要根据其是要在台式机还是手机上运行而有所不同。 一些开始寻找信息的地方

  • 问题内容: 我想学习如何为html创建具有特殊属性和行为的自定义标签,如果有人可以提供建议,我将不胜感激。 问题答案: HTML5Rocks.com上有一篇有趣且深入的文章,介绍如何使用自定义元素:自定义元素:在HTML中定义新元素 这是该文章的摘录。 实例化元素 创建元素的常用技术仍然适用于自定义元素。与任何标准元素一样,它们可以用HTML声明或使用JavaScript在DOM中创建。实例化自定

  • 我正在使用Spring Boot和EhCache开发一个日历应用程序。我正在尝试缓存以下方法: 挑战是我想操纵返回的缓存结果。例如,检查是否存在针对给定日期但针对不同用户的缓存,然后返回它(只要两个用户都满足某些条件)。 所以,在返回结果之前,我想: 获取所有缓存项的列表 我认为最好是创建一个自定义缓存管理器,该管理器将使用缓存concert执行所有操作,并使用默认的自动配置缓存用于所有其他方法,

  • 本文向大家介绍Android如何创建自定义ActionBar,包括了Android如何创建自定义ActionBar的使用技巧和注意事项,需要的朋友参考一下 当多个界面都有很多相似部分时,可以考虑创建一个功能较全的模板。而在需要时,可以通过引用模板来实现自己想要实现的功能。比如适配器 Adapter,当很多的适配器都差不多时,就可以通过打造一个通用的适配器来实现。本例中主要是如何创建自定义的 Act