java - JobStoreTX 的 Spring boot + Quartz + Oracle 问题
问题描述
我正在使用 Spring boot + Quartz + Oracle 创建一个应用程序,我想将调度保存在数据库中(持久性,以防服务器崩溃)。使用 RAMJobStore 可以正常工作,但是当我尝试使用 JobStoreTX 时它不起作用,它总是使用 RAMJobStore,问题出在哪里?我肯定会犯很多错误,但这是我第一个使用 spring boot + Quartz 的应用程序,你能给我一个想法吗?
事件将被动态创建,接收控制器中的信息。
application.yaml(除了Quartz,应用连接数据库查询表,但是应用和Quartz会使用同一个数据库)
hibernate:
globally_quoted_identifiers: true
show_sql: true
logging:
level:
org:
hibernate:
SQL: ${hibernate.logging}
pattern:
console: '%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n'
server:
port: ${port}
spring:
activemq:
broker-url: ${activemq-url}
password: ${activemq-password}
user: ${activemq-user}
datasource:
driver-class-name: ${driverClassName}
password: ${ddbb-password}
jdbcUrl: ${ddbb-url}
username: ${ddbb-user}
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.Oracle12cDialect
quartz:
job-store-type: jdbc
jdbc:
initialize-schema: never
properties:
org:
quartz:
scheduler:
instanceId: AUTO
jobStore:
useProperties: true
isClustered: false
clusterCheckinInterval: 5000
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
dataSource: quartzDataSource
dataSource:
quartzDataSource:
driver: oracle.jdbc.driver.OracleDriver
URL: ${ddbb-url}
user: ${ddbb-user}
password: ${ddbb-password}
类调度器配置
@Configuration
public class SchedulerConfiguration {
@Bean
public SchedulerFactoryBean schedulerFactory(ApplicationContext applicationContext) {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setJobFactory(new AutoWiringSpringBeanJobFactory());
return schedulerFactoryBean;
}
@Bean
public Scheduler scheduler(ApplicationContext applicationContext) throws SchedulerException {
Scheduler scheduler = schedulerFactory(applicationContext).getScheduler();
scheduler.start();
return scheduler;
}
@Bean
@QuartzDataSource
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource quartzDataSource() {
return DataSourceBuilder.create().build();
}
}
类 AutoWiringSpringBeanJobFactor
public class AutoWiringSpringBeanJobFactory extends SpringBeanJobFactory implements
ApplicationContextAware{
private transient AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(final ApplicationContext context) {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}
职位类别
@Component
public class CampaignJob implements Job{
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("Hi, the job works");
}
}
它创建的调度程序所在的类
public class ManagerServiceImpl implements ManagerService {
@Autowired
private ProducerQueue producer;
@Autowired
private ManagementDatabase managementDatabase;
@Autowired
private Scheduler scheduler;
@Override
public String processCampaign(ScheduleCampaign scheduleCampaign) {
try {
ZonedDateTime dateTime = ZonedDateTime.of(scheduleCampaign.getDateTime(), scheduleCampaign.getTimeZone());
JobDetail jobDetail = buildJobDetail(scheduleCampaign);
Trigger trigger = buildJobTrigger(jobDetail, dateTime);
scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
System.out.println("There was an error creating the scheduler: "+e);
}
return "Scheduler created";
}
private JobDetail buildJobDetail(ScheduleCampaign scheduleCampaign) {
JobDataMap jobDataMap = new JobDataMap();
System.out.println("Function: buildJobDetail - campaign value: "+scheduleCampaign.getCampaign());
jobDataMap.put("campaign", scheduleCampaign.getCampaign());
return JobBuilder.newJob(CampaignJob.class)
.withIdentity(UUID.randomUUID().toString(), "campaign-jobs")
.requestRecovery(true)
.storeDurably(true)
.withDescription("campaign job planned")
.usingJobData(jobDataMap)
.storeDurably()
.build();
}
private Trigger buildJobTrigger(JobDetail jobDetail, ZonedDateTime startAt) {
return TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withIdentity(jobDetail.getKey().getName(), "campaign-triggers")
.withDescription("campaign job Trigger")
.startAt(Date.from(startAt.toInstant()))
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withMisfireHandlingInstructionFireNow())
.build();
}
}
日志
2020-12-28 16:16:08 INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2020-12-28 16:16:09 INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
2020-12-28 16:16:09 INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2020-12-28 16:16:10 INFO org.hibernate.Version - HHH000412: Hibernate ORM core version 5.4.23.Final
2020-12-28 16:16:10 INFO org.quartz.impl.StdSchedulerFactory - Using default implementation for ThreadExecutor
2020-12-28 16:16:10 INFO o.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2020-12-28 16:16:10 INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.3.2 created.
2020-12-28 16:16:10 INFO org.quartz.simpl.RAMJobStore - RAMJobStore initialized.
2020-12-28 16:16:10 INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.3.2) 'schedulerFactory' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
解决方案
如果您也为石英作业指向同一个数据库,请尝试自动连接您的应用程序默认数据源。
以下配置适用于我的 PostgreSQL
@Autowired
DataSource dataSource;
@Autowired
JobFactory jobFactory;
@Bean
public JobFactory jobFactory(ApplicationContext applicationContext) {
AutoWiringSpringBeanJobFactory jobFactory = new AutoWiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
@Bean
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setOverwriteExistingJobs(true);
factory.setAutoStartup(true);
factory.setDataSource(dataSource);
factory.setJobFactory(jobFactory);
factory.setQuartzProperties(quartzProperties());
return factory;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
推荐阅读
- sql-server - 如何在 SQL Server 2012 中查看 sa 密码?
- typescript - 混合应用程序和全局管道无法协同工作
- github - 如何在 Github 中合并子模块
- python - 在admin页面django中定义一个可以修改的全局变量,以及关于字段的问题
- angularjs - 你如何在 Jasmine 测试中模拟 angularJS 控制器 $scope 变量?
- wordpress - 从多个目录访问多语言 WordPress 博客
- python - 我正在尝试用 Python 制作闹钟(来自教程),Playsound 没有激活声音
- string - Powershell - 选择文件名的特定部分
- java - 使用比较器对字符串数组进行排序(特定排序情况)
- ios - AVCaptureDevice 的 exposurePointOfInterest 不起作用