diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java index c7f36d12eec..871304c5063 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java @@ -108,6 +108,7 @@ abstract class ConnectionFactoryConfigurations { map.from(pool.getMaxIdleTime()).to(builder::maxIdleTime); map.from(pool.getMaxLifeTime()).to(builder::maxLifeTime); map.from(pool.getMaxAcquireTime()).to(builder::maxAcquireTime); + map.from(pool.getAcquireRetry()).to(builder::acquireRetry); map.from(pool.getMaxCreateConnectionTime()).to(builder::maxCreateConnectionTime); map.from(pool.getInitialSize()).to(builder::initialSize); map.from(pool.getMaxSize()).to(builder::maxSize); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java index 210967c545d..3591b54a3c0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java @@ -158,6 +158,11 @@ public class R2dbcProperties { */ private Duration maxAcquireTime; + /** + * Number of acquire retries if the first acquire attempt fails. + */ + private int acquireRetry = 1; + /** * Maximum time to validate a connection from the pool. By default, wait * indefinitely. @@ -234,6 +239,14 @@ public class R2dbcProperties { this.maxAcquireTime = maxAcquireTime; } + public int getAcquireRetry() { + return this.acquireRetry; + } + + public void setAcquireRetry(int acquireRetry) { + this.acquireRetry = acquireRetry; + } + public Duration getMaxCreateConnectionTime() { return this.maxCreateConnectionTime; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java index 9ef8ee88f39..926b56bccc5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ import org.assertj.core.api.InstanceOfAssertFactories; import org.assertj.core.api.InstanceOfAssertFactory; import org.assertj.core.api.ObjectAssert; import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; import org.springframework.beans.factory.BeanCreationException; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -47,6 +48,7 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.r2dbc.core.DatabaseClient; +import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -82,8 +84,8 @@ class R2dbcAutoConfigurationTests { this.contextRunner .withPropertyValues("spring.r2dbc.url:r2dbc:h2:mem:///" + randomDatabaseName(), "spring.r2dbc.pool.max-size=15", "spring.r2dbc.pool.max-acquire-time=3m", - "spring.r2dbc.pool.min-idle=1", "spring.r2dbc.pool.max-validation-time=1s", - "spring.r2dbc.pool.initial-size=0") + "spring.r2dbc.pool.acquire-retry=5", "spring.r2dbc.pool.min-idle=1", + "spring.r2dbc.pool.max-validation-time=1s", "spring.r2dbc.pool.initial-size=0") .run((context) -> { assertThat(context).hasSingleBean(ConnectionFactory.class) .hasSingleBean(ConnectionPool.class) @@ -96,6 +98,9 @@ class R2dbcAutoConfigurationTests { assertThat(poolMetrics.getMaxAllocatedSize()).isEqualTo(15); assertThat(connectionPool).hasFieldOrPropertyWithValue("maxAcquireTime", Duration.ofMinutes(3)); assertThat(connectionPool).hasFieldOrPropertyWithValue("maxValidationTime", Duration.ofSeconds(1)); + Mono create = (Mono) ReflectionTestUtils.getField(connectionPool, "create"); + assertThat(create.getClass().getName()).endsWith("MonoRetry"); + assertThat(create).hasFieldOrPropertyWithValue("times", 5L); } finally { connectionPool.close().block();