Skip to content

JdbcStoreTypeConfiguration picks transaction of primary data source when Quartz data source is not the primary data source #20184

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

Closed
breun opened this issue Feb 14, 2020 · 2 comments
Labels
type: bug A general bug
Milestone

Comments

@breun
Copy link
Contributor

breun commented Feb 14, 2020

QuartzAutoConfiguration.JdbcStoreTypeConfiguration will use the transaction manager of the primary data source when an application has multiple data sources and a non-primary data source is annotated with @QuartzDataSource.

Consider this configuration of beans:

@Primary
@Bean
public HikariDataSource primaryDataSource() {
    HikariConfig config = new HikariConfig();
    config.setJdbcUrl("jdbc:postgresql://localhost:5432/postgres");
    config.setDriverClassName("org.postgresql.Driver");
    config.setUsername("postgres");
    config.setPassword("mysecretpassword");
    config.setAutoCommit(false);
    config.setIdleTimeout(10000);
    config.setPoolName("Primary pool");
    return new HikariDataSource(config);
}

@Primary
@Bean
public DataSourceTransactionManager primaryDataSourceTransactionManager() {
    return new DataSourceTransactionManager(primaryDataSource());
}

@QuartzDataSource
@Bean
public HikariDataSource quartzDataSource() {
    HikariConfig config = new HikariConfig();
    config.setJdbcUrl("jdbc:postgresql://localhost:5432/quartzexample");
    config.setDriverClassName("org.postgresql.Driver");
    config.setUsername("quartzexample");
    config.setPassword("quartzexamplepw");
    config.setAutoCommit(false);
    config.setIdleTimeout(10000);
    config.setPoolName("Quartz pool");
    return new HikariDataSource(config);
}

@Bean
public DataSourceTransactionManager quartzDataSourceTransactionManager() {
    return new DataSourceTransactionManager(quartzDataSource());
}

In org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration.JdbcStoreTypeConfiguration#dataSourceCustomizer you will see the transaction manager for the primary datasource gets set on the SchedulerFactoryBean.

In this scenario actually the transaction manager of the datasource annotated with @QuartzDataSource should be set on the SchedulerFactoryBean. As a workaround this can be accomplished by adding a SchedulerFactoryBeanCustomizer like this:

@Order(Ordered.HIGHEST_PRECEDENCE)
@Bean
public SchedulerFactoryBeanCustomizer schedulerFactoryBeanCustomizer() {
    return schedulerFactoryBean -> schedulerFactoryBean.setTransactionManager(quartzDatasourceTransactionManager());
}

But ideally auto-configuration would take of this automatically of course.

This is using Spring Boot 2.2.4.RELEASE.

@breun breun changed the title JdbcStoreTypeConfiguration picks transaction of primary data source when Quartz datasource is not the primary data source JdbcStoreTypeConfiguration picks transaction of primary data source when Quartz data source is not the primary data source Feb 14, 2020
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Feb 14, 2020
@snicoll
Copy link
Member

snicoll commented Feb 14, 2020

Thanks for the report.

But ideally auto-configuration would take of this automatically of course.

For that to be possible we would need a way to tie the transaction manager (implementation) to its DataSource. Looping over the available TransactionManager to introspect them would be a possibility but that makes me a bit nervous. A better approach would be to use a qualifier on the TransactionManager bean.

@snicoll snicoll added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Feb 14, 2020
@snicoll snicoll added this to the 2.1.x milestone Feb 14, 2020
@breun
Copy link
Contributor Author

breun commented Feb 14, 2020

My current workaround is annotating the transaction manager with my own @QuartzTransactionManager annotation and an extra SchedulerFactoryBeanCustomizer bean that looks for a transaction manager with this annotation and sets this on the SchedulerFactoryBean as the transaction manager.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants