Kondisi balapan Spring Quartz Scheduler

Saya menduga masalahnya adalah setOverwriteExistingJobs SchedulerFactoryBean tidak menawarkan perlindungan yang cukup.

Satu node akan menginisialisasi penjadwal dan akan memutuskan untuk mengganti pemicu (breakpoint org.quartz.impl.jdbcjobstore.SimpleTriggerPersistenceDelegate#deleteExendedTriggerProperties )

Tepat setelah metode ini dijalankan, pemicunya tidak akan ada lagi di database sehingga ketika node lain di cluster mencoba membacanya (org.quartz.impl.jdbcjobstore.JobStoreSupport#retrieveTrigger), pemicunya akan gagal dengan pengecualian di bawah . Karena pengecualian ini, seluruh aplikasi akan gagal untuk memulai (bukan hanya penjadwal).

Disebabkan oleh: org.quartz.JobPersistenceException: Tidak dapat mengambil pemicu: Tidak ditemukan catatan untuk pemilihan Pemicu dengan kunci:

Lognya dapat ditemukan di https://github.com/apixandru/case-study/tree/master/spring-boot-quartz/logs (Pengecualian dapat ditemukan pada node Server-1 setelah restart ke-4)

Untuk keseluruhan proyek yang menunjukkan masalah ini, buka https://github.com/apixandru/case-study/tree/master/spring-boot-quartz

Cara kami mengonfigurasi penjadwal ada di sini

@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;
}

Hal ini sering terjadi di server kerja kami tetapi jauh lebih sulit untuk mendapatkannya secara lokal (mungkin karena fakta bahwa server sebenarnya berdedikasi dan memiliki daya lebih besar daripada mesin lokal saya?)

Untuk mendapatkan bug di mesin mana pun, mulai satu server dalam mode debug dan letakkan breakpoint di SimpleTriggerPersistenceDelegate.deleteExendedTriggerProperties dan setelah dijalankan, mulai server kedua dan Anda akan mendapatkan pengecualian ini

Bagaimanapun, saya berhasil mendapatkan kesalahan ini secara lokal juga setelah sekitar 40 penerapan ulang ke server weblogic cluster lokal saya.


person Alexandru    schedule 24.09.2016    source sumber


Jawaban (1)


Masalahnya adalah secara default tidak ada pengelola transaksi yang digunakan, sehingga tidak ada penguncian yang digunakan.

Untuk mengatasi masalah ini, diperlukan untuk memanggil metode setTransactionManager schedulerFactoryBean.

person Alexandru    schedule 27.09.2016