2016-09-24 119 views
3

我懷疑問題是SchedulerFactoryBean的setOverwriteExistingJobs沒有提供足夠的保護。春季石英調度競賽條件

一個節點將被初始化調度,它會決定更換觸發器(斷點org.quartz.impl.jdbcjobstore.SimpleTriggerPersistenceDelegate#deleteExtendedTriggerProperties)

正確的IT執行此方法後,觸發不會在數據庫中,當羣集中的另一個節點嘗試讀取它時(org.quartz.impl.jdbcjobstore.JobStoreSupport#retrieveTrigger),它將失敗,並出現下面的異常。由於這個例外,整個應用程序將無法啓動(不僅僅是調度程序)。

產生的原因:org.quartz.JobPersistenceException:無法檢索 觸發:沒有記錄發現觸發的選擇與關鍵:

日誌可以在https://github.com/apixandru/case-study/tree/master/spring-boot-quartz/logs (例外情況可查詢4日重啓後的服務器,1個節點)

有關演示這個問題去https://github.com/apixandru/case-study/tree/master/spring-boot-quartz

整個項目上找到我們配置調度的方式是這裏

@Bean 
JobDetailFactoryBean jobFactoryBean() { 
    JobDetailFactoryBean bean = new JobDetailFactoryBean(); 
    bean.setDurability(true); 
    bean.setName("Sampler"); 
    bean.setJobClass(SampleJob.class); 
    return bean; 
} 

@Bean 
SimpleTriggerFactoryBean triggerFactoryBean(JobDetailFactoryBean jobFactoryBean) { 
    SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean(); 
    bean.setName("Sampler Trigger"); 
    bean.setRepeatInterval(20_000); 
    bean.setJobDetail(jobFactoryBean.getObject()); 
    return bean; 
} 

@Bean 
SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean triggerFactoryBean, DataSource dataSource, Dependency dependency) { 
    Properties props = new Properties(); 
    props.put("org.quartz.scheduler.instanceId", "AUTO"); 
    props.put("org.quartz.jobStore.isClustered", "true"); 

    SchedulerFactoryBean bean = new SchedulerFactoryBean(); 
    bean.setTriggers(triggerFactoryBean.getObject()); 
    bean.setSchedulerName("Demo Scheduler"); 
    bean.setSchedulerContextAsMap(Collections.singletonMap("dependency", dependency)); 
    bean.setOverwriteExistingJobs(true); 
    bean.setDataSource(dataSource); 
    bean.setQuartzProperties(props); 

    return bean; 
} 

這種情況發生了很多我們的工作的服務器上,但它的很多困難在本地(獲得可能是由於實際服務器專用,並有更多的動力比我的本地機器?)

要在任何機器上的漏洞,開始在調試模式下一個服務器,並把一個斷點SimpleTriggerPersistenceDelegate.deleteExtendedTriggerProperties,它只是執行後,啓動第二個服務器,你會得到這個異常

無論如何,我設法得到這個錯誤本地以及約4 0重新部署到本地羣集的weblogic服務器。

回答

1

問題是,默認情況下沒有使用事務管理器,因此不使用鎖定。

要解決該問題,需要調用schedulerFactoryBean的setTransactionManager方法。