-
Notifications
You must be signed in to change notification settings - Fork 41.2k
Suggestion to support LazyConnectionDataSourceProxy #15480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
a `DataSourceProperties` class to enable a `LazyConnectionDataSourceBeanPostProcessor`. BeanPostProcessor wraps an auto-configured DataSource in a `LazyConnectionDataSourceProxy`. It will be added only if a `spring.datasource.lazy-connection` property has `true` and `LazyConnectionDataSourceProxy` class is present. The default value of the spring.datasource.lazy-connection` property is `false`, which means is disabled by default. closes #spring-projectsgh-15480
a DataSourceProperties class to enable a LazyConnectionDataSourceBeanPostProcessor. BeanPostProcessor wraps an auto-configured DataSource in a LazyConnectionDataSourceProxy. It will be added only if a spring.datasource.lazy-connection property has true and a LazyConnectionDataSourceProxy class is present. The default value of the spring.datasource.lazy-connection property is false, which means a lazy-connection feature is disabled by default. closes spring-projectsgh-15480
a DataSourceProperties class to enable a LazyConnectionDataSourceBeanPostProcessor. BeanPostProcessor wraps an auto-configured DataSource in a LazyConnectionDataSourceProxy. It will be added only if a spring.datasource.lazy-connection property has true and a LazyConnectionDataSourceProxy class is present. The default value of the spring.datasource.lazy-connection property is false, which means a lazy-connection feature is disabled by default. closes spring-projectsgh-15480
a DataSourceProperties class to enable a LazyConnectionDataSourceBeanPostProcessor. BeanPostProcessor wraps an auto-configured DataSource in a LazyConnectionDataSourceProxy. It will be added only if a spring.datasource.lazy-connection property has true and a LazyConnectionDataSourceProxy class is present. The default value of the spring.datasource.lazy-connection property is false, which means a lazy-connection feature is disabled by default. closes spring-projectsgh-15480
a DataSourceProperties class to enable a LazyConnectionDataSourceBeanPostProcessor. BeanPostProcessor wraps an auto-configured DataSource in a LazyConnectionDataSourceProxy. It will be added only if a spring.datasource.lazy-connection property has true and a LazyConnectionDataSourceProxy class is present. The default value of the spring.datasource.lazy-connection property is false, which means a lazy-connection feature is disabled by default. closes spring-projectsgh-15480
a DataSourceProperties class to enable a LazyConnectionDataSourceBeanPostProcessor. BeanPostProcessor wraps an auto-configured DataSource in a LazyConnectionDataSourceProxy. It will be added only if a spring.datasource.lazy-connection property has true and a LazyConnectionDataSourceProxy class is present. The default value of the spring.datasource.lazy-connection property is false, which means a lazy-connection feature is disabled by default. closes spring-projectsgh-15480
HI, all. While it would be great to have this in place, I was able to write some code to wrap an underlying Data Source in a LazyConnectionDataSourceProxy. This code specifically handles Hikari, but could be modified for the other data sources Spring Boot uses, or for some other data source all together if wanted. It's conditional so that you can control it by a property setting ("my.datasource.lacy-connections"). (We have this in a shared library for our own Spring Boot starters, that we use across multiple applications) And - it should be fairly easy to yank once Spring Boot provides this functionality natively. My testing shows it works well, and interacts nicely with the Spring Boot auto-configured transaction handling and JdbcTemplate (along with NamedParameterJdbcTemplate)
|
We had the same problem and used @rpsandiford's suggestion above. @Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public HikariDataSource hikariDataSource(DataSourceProperties properties) {
HikariDataSource hikariDataSource = createDataSource(properties, HikariDataSource.class);
if (StringUtils.hasText(properties.getName())) {
hikariDataSource.setPoolName(properties.getName());
}
return hikariDataSource;
}
protected static <T> T createDataSource(DataSourceProperties properties, Class<? extends DataSource> type) {
return (T) properties.initializeDataSourceBuilder().type(type).build();
}
@Primary
@Bean
public DataSource dataSource(HikariDataSource hikariDataSource) {
// Wrap hikariDataSource in a LazyConnectionDataSourceProxy
LazyConnectionDataSourceProxy lazyDataSource = new LazyConnectionDataSourceProxy();
lazyDataSource.setTargetDataSource(hikariDataSource);
return lazyDataSource;
} (you may need to disable boot datasources by adding |
We got some related efforts in Spring's core JDBC support for 6.1.2: In addition to enabling late-bound connection pool routing, a lazy connection setup goes along nicely with virtual thread scaling scenarios: |
We need this, too! We love LazyConnectionDataSourceProxy but it is difficult to configure. I just tried to switch to the new docker-compose support. Now I am doing it like this with the help of @nwwerum It would be so nice to have a property to activate lazy connections. It is really a performance boost, in my opinion.
|
Hi @philwebb , team meeting was removed on March 18. Out of curiosity what was decided. Since there are improvements in Spring framework , Can we expect any forward work on this ticket? |
One work around that works and supports @Configuration(proxyBeanMethods = false)
class LazyConnectionDataSourceProxyConfig implements BeanFactoryPostProcessor {
/**
* Processes the bean factory after its standard initialization.
* This method:
* 1. Registers a new LazyConnectionDataSourceProxy as the primary datasource
*
* @throws BeansException if the "dataSource" bean is not found
*/
@Override
public void postProcessBeanFactory(@NonNull ConfigurableListableBeanFactory beanFactory) throws BeansException {
DefaultListableBeanFactory listableBeanFactory = (DefaultListableBeanFactory) beanFactory;
if (!listableBeanFactory.containsBean("dataSource")) {
throw new BeansException("Required 'dataSource' bean is not defined") {};
}
// Register LazyConnectionDataSourceProxy as a primary bean
listableBeanFactory.registerBeanDefinition(
"lazyConnectionDataSourceProxy", createLazyConnectionDataSourceProxyDefinition(listableBeanFactory));
}
private GenericBeanDefinition createLazyConnectionDataSourceProxyDefinition(
DefaultListableBeanFactory listableBeanFactory) {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(LazyConnectionDataSourceProxy.class);
beanDefinition.setInstanceSupplier(() -> new LazyConnectionDataSourceProxy(
listableBeanFactory.getBean("dataSource", DataSource.class)));
beanDefinition.setPrimary(true); // Set this bean as primary
return beanDefinition;
}
} |
@rajadilipkolli I actually can't remember the outcome of the team meeting I'm afraid. We've not had the time to really investigate the feature in any detail yet. |
Are there any news on this? |
It would be awesome if we also could add the read-only db properties in application conf. Since the |
Hi,
I would like to suggest a support for
LazyConnectionDataSourceProxy
in spring-boot.Here is my opinion:
Transaction management in spring:
When a transactional method(
@Transactional
) is called, the configured impl ofPlatformTransactionManager
kicks in and starts/prepare transaction logic(callAbstractPlatformTransactionManager#doBegin
).In the implementation of starting transaction(e.g:
JpaTransactionManager
,HibernateTransactionManager
), when@Transactional
definition has non default isolation level or readonly flag is set to true, it acquires a physical connection and set isolation level and/or readonly flag to the connection in its preparation phase. (call toDataSourceUtils#prepareConnectionForTransaction
)Since this happens before invoking the actual target method, this consumes a connection from pool(underlying
DataSource
) regardless of the method really needs a connection or not.It is problematic especially on high traffic application with:
It is better to delay getting the physical connection as much as possible.
LazyConnectionDataSourceProxy
in spring solves this problem. When isolation-level, read-only flag, etc methods are called, this proxy internally keeps those values. Physical connection acquisition is delayed until connection is really required.Currently, spring-boot doesn't have any support for
LazyConnectionDataSourceProxy
.My suggestion is to add a configuration of
LazyConnectionDataSourceProxy
in spring-boot.Probably, application property with
spring.datasource.lazy-connection=true
would wrap the datasource withLazyConnectionDataSourceProxy
. I also think it is beneficial to turn this on by default.LazyConnectionDataSourceProxy
should be recommended more, in general, IMO.Thanks,
The text was updated successfully, but these errors were encountered: