首页 文章

为什么Quartz作业没有被执行(尽管QUARTZ表正在使用适当的作业详细信息进行更新)

提问于
浏览
3

我通过以下方式在applicationcontext文件中定义了SchedulerFactoryBean:

<bean id="quartzscheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
    <property name="autoStartup">
        <value>true</value>
    </property>
    <property name="quartzProperties">
        <props>
            <prop key="org.quartz.scheduler.instanceId">AUTO</prop>
            <prop key="org.quartz.scheduler.instanceName">MyClusteredScheduler</prop>
            <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
            <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
            <prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
            <prop key="org.quartz.jobStore.isClustered">true</prop>
            <prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop>
            <prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
        </props>
    </property>
    <property name="dataSource">
        <ref bean="quartzdataSource" />
    </property>
</bean>

<bean id="quartzdataSource"
            class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3305/quartz" />
    <property name="username" value="root" />
    <property name="password" value="root" />
</bean>

这是我的工作类,它实际上是一个实体bean类,按以下方式定义:

@Entity
@Table(name = "DATABASEMONITOR")
public class DatabaseMonitor implements Serializable, Job {

    @Id
    @GeneratedValue
    @Column(name = "ID", unique = true, nullable = false)
    private Integer id;

    @Column(name = "NAME", nullable = false)
    private String name;

    public DatabaseMonitor(String name, String sqlQuery){
        this.name = name;
        this.sqlQuery = sqlQuery;
    }

    @Override
    public void execute(JobExecutionContext context)
            throws JobExecutionException {
        System.out.println("inside job");
    }
}

这是我的调度程序控制器类:

public class SchedulerController {

    public static void addJob(DatabaseMonitor databaseMonitor){

        JobDetail job = new JobDetail();
        job.setName(databaseMonitor.getName());
        job.setJobClass(DatabaseMonitor.class);

        CronTrigger trigger = new CronTrigger();
        trigger.setName(databaseMonitor.getName());
        try {
            trigger.setCronExpression("0/2 * * * * ?");
            Scheduler scheduler = (Scheduler) BeansManager.getInstance().getBean("quartzscheduler");
            scheduler.scheduleJob(job, trigger);
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

    }

}

从主类我调用这个调度函数来在运行时添加作业:

DatabaseMonitor databaseMonitor = new DatabaseMonitor(new Date().toString(), "query string");
        SchedulerController.addJob(databaseMonitor);

现在问题是一切正常,没有任何异常,工作细节在预定义的石英数据库细节中得到更新 . 但这项工作没有得到执行 . 你能帮我解决这个问题吗?

2 回答

  • 0

    您的配置缺少必需的 org.quartz.threadPool.classorg.quartz.threadPool.threadCount 属性 .

    见:http://quartz-scheduler.org/documentation/quartz-1.x/configuration/ConfigThreadPool

  • 0

    你的 DatabaseMonitor 应该有一个默认的构造函数 . Quartz将尝试执行 JobDetail . 并且 JobDetail 将从头开始创建 DatabaseMonitor 并执行其execute方法 . 由于 DatabaseMonitor 没有默认构造函数,因此无法执行 .

    更新

    既然你已经有了一个默认的构造函数,我建议稍微重构一下 . 我使用带有 spring 的2.2.1版石英,所以一些类名可能会有所不同 .

    首先让你的实体分成两部分 .

    import javax.persistence.Column;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    
    public class DatabaseMonitor {
        @Id
        @GeneratedValue
        @Column(name = "ID", unique = true, nullable = false)
        private Integer id;
    
        @Column(name = "NAME", nullable = false)
        private String name;
    
        @Column(name = "SQL_QUERY", nullable = false)
        private String sqlQuery;
    
        // Getters && Setters && Def. Const etc.
    }
    

    我稍后会解释工作部分 . 然后让你的控制器重构为一个spring bean .

    import org.quartz.JobDataMap;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.impl.JobDetailImpl;
    import org.quartz.impl.triggers.CronTriggerImpl;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.text.ParseException;
    
    @Component
    public class SchedulerController {
    
        @Autowired
        Scheduler scheduler;
    
        public void addJob(DatabaseMonitor databaseMonitor) {
    
            final JobDataMap jobDataMap = new JobDataMap();
            jobDataMap.put("sqlQuery", databaseMonitor.getSqlQuery());
            final JobDetailImpl jobDetail = new JobDetailImpl();
            jobDetail.setName(databaseMonitor.getName());
            jobDetail.setDurability(true);
            jobDetail.setJobDataMap(jobDataMap);
            jobDetail.setJobClass(DatabaseJob.class);
    
            try {
                final CronTriggerImpl trigger = new CronTriggerImpl();
                trigger.setCronExpression("0/2 * * * * ?");
                trigger.setName(databaseMonitor.getName());
                scheduler.scheduleJob(jobDetail, trigger);
            } catch (ParseException | SchedulerException e) {
                e.printStackTrace();
            }
        }
    }
    

    如您所见,我正在使用JobDataMap将参数传递给我的作业 . 这个参数可能是sqlQuery . 然后检查我们的工作 .

    import org.quartz.Job;
    import org.quartz.JobDataMap;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    import java.io.Serializable;
    
    public class DatabaseJob implements Job, Serializable {
        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            final JobDataMap jobDataMap = context.getMergedJobDataMap();
            final String sqlQuery = jobDataMap.getString("sqlQuery");
            System.out.println("SqlQuery: " + sqlQuery);
        }
    }
    

    我正从上下文中读取我的查询 . 我的工作不包含任何州 . 在您的实施中,您的工作也是一个实体 . Hibernate(或其他JPA实现)代理几乎所有东西,并拥有很多状态 . 这会因石英执行而中断 .

    更新2

    我创建了一个示例应用程序并将其放到github .

相关问题