2017-01-03 5 views
0

Для моего приложения, мы используем org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource весной вКварц JDBCJobStore с RoutingDataSource

Целевых DataSources настроены и выбраны на основе домена URL запроса.

Eg: 

    qa.example.com ==> target datasource = DB1 
    qa-test.example.com ==> target datasource = DB2 

Ниже приводится конфигурация для одной и той же

@Bean(name = "dataSource") 
    public DataSource dataSource() throws PropertyVetoException, ConfigurationException { 
     EERoutingDatabase routingDB = new EERoutingDatabase(); 

     Map<Object, Object> targetDataSources = datasourceList(); 
     routingDB.setTargetDataSources(targetDataSources); 

     return routingDB; 
    } 

public class EERoutingDatabase extends AbstractRoutingDataSource { 

    @Override 
    protected Object determineCurrentLookupKey() { 
     // This is derived from the request's URL/Domain 
     return SessionUtil.getDataSourceHolder(); 
    } 
} 

Задача теперь использует кварцевые JDBCJobStore для хранения кварцевых рабочих мест/триггеры.

Предпочтительный вариант - использование JobStoreCMT.

Мы использовали следующие конфигурации

@Configuration 
public class QuartzConfig { 
    private static final Logger LOG = LoggerFactory.getLogger(QuartzConfig.class); 
    private static final String QUARTZ_CONFIG_FILE = "ee-quartz.properties"; 


    @Autowired 
    private DataSource dataSource; 

    @Autowired 
    private PlatformTransactionManager transactionManager; 

    @Autowired 
    private ApplicationContext applicationContext; 

    /** 
    * Spring wrapper over Quartz Scheduler bean 
    */ 
    @Bean(name="quartzRealTimeScheduler") 
    SchedulerFactoryBean schedulerFactoryBean() { 
     LOG.info("Creating QUARTZ Scheduler for real time Job invocation"); 
     SchedulerFactoryBean factory = new SchedulerFactoryBean(); 
     factory.setConfigLocation(new ClassPathResource(QUARTZ_CONFIG_FILE)); 
     factory.setDataSource(dataSource); 
     factory.setTransactionManager(transactionManager); 
     factory.setJobFactory(springBeanJobFactory()); 
     factory.setWaitForJobsToCompleteOnShutdown(true); 
     factory.setApplicationContextSchedulerContextKey("applicationContext"); 
     return factory; 
    } 

    @Bean 
    public SpringBeanJobFactory springBeanJobFactory() { 
     AutoWiringSpringBeanJobFactory jobFactory = new AutoWiringSpringBeanJobFactory(); 
     jobFactory.setApplicationContext(applicationContext); 
     jobFactory.setIgnoredUnknownProperties("applicationContext"); 
     return jobFactory; 
    } 
} 

и после является конфигурацией в кварцевом файле свойств (ee-quartz.properties)

org.quartz.scheduler.instanceId=AUTO 
org.quartz.jobStore.useProperties=false 
org.quartz.jobStore.misfireThreshold: 60000 
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate 

При запуске приложения, после исключения происходит

Caused by: java.lang.IllegalStateException: Cannot determine target DataSource for lookup key [null] 
    at org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource.determineTargetDataSource(AbstractRoutingDataSource.java:202) ~[spring-jdbc-4.1.6.RELEASE.jar:4.1.6.RELEASE] 
    at com.expertly.config.EERoutingDatabase.determineTargetDataSource(EERoutingDatabase.java:60) ~[EERoutingDatabase.class:na] 
    at org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource.getConnection(AbstractRoutingDataSource.java:164) ~[spring-jdbc-4.1.6.RELEASE.jar:4.1.6.RELEASE] 
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) ~[spring-jdbc-4.1.6.RELEASE.jar:4.1.6.RELEASE] 
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) ~[spring-jdbc-4.1.6.RELEASE.jar:4.1.6.RELEASE] 
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:289) ~[spring-jdbc-4.1.6.RELEASE.jar:4.1.6.RELEASE] 
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:329) ~[spring-jdbc-4.1.6.RELEASE.jar:4.1.6.RELEASE] 
    at org.springframework.scheduling.quartz.LocalDataSourceJobStore.initialize(LocalDataSourceJobStore.java:149) ~[spring-context-support-4.0.1.RELEASE.jar:4.0.1.RELEASE] 
    at org.quartz.impl.StdSchedulerFactory.instantiate(StdSchedulerFactory.java:1321) ~[quartz-2.2.2.jar:na] 
    at org.quartz.impl.StdSchedulerFactory.getScheduler(StdSchedulerFactory.java:1525) ~[quartz-2.2.2.jar:na] 
    at org.springframework.scheduling.quartz.SchedulerFactoryBean.createScheduler(SchedulerFactoryBean.java:599) ~[spring-context-support-4.0.1.RELEASE.jar:4.0.1.RELEASE] 
    at org.springframework.scheduling.quartz.SchedulerFactoryBean.afterPropertiesSet(SchedulerFactoryBean.java:482) ~[spring-context-support-4.0.1.RELEASE.jar:4.0.1.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612) ~[spring-beans-4.0.1.RELEASE.jar:4.0.1.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549) ~[spring- 

beans-4.0.1.RELEASE.jar: 4.0.1.RELEASE]

кажется, что

  1. Кварц пытается создать связи с моим источником данных авансовый. Поскольку мой dataSource не является конкретным (его маршрутизирующий dataSource) и дополнительно не имеет сведений, к которому целевой Db подключается (в момент конфигурации), он не работает

  2. Есть ли у нас какие-либо положения, в которых могут быть использованы кварц использовать с RoutingDataSource? Если нет, что будет следующим лучшим?

ответ

0

В идеале вы можете попробовать SchedulerFactoryBean как @Lazy.

Но кажется, что ленивая инициализация не работает bug, есть также работа вокруг, перечисленная в комментариях.

Создать schedulerFactory боб динамически после ContextRefreshedEvent получил от корневого контекста.

Сообщите нам, если это работает.

Смежные вопросы