前言

我们做到这里已经对Quartz定时器组件已经是学会了基本的使用了。但是我们有没有想过任务开启之后万一断掉了,当机了我们怎么办,你是否还想继续执行原先的任务。我们普通的创建是把任务放在内存中存储,如果内存被释放掉,任务也就消失了,那怎么办哪,不得不说这个组件还是很厉害的。他已经帮我们想过了解方案---就是放到数据库。

  Quartz插一嘴:

quartz在任务中分为两种:有状态和无状态执行。

有状态:对于同一个 trigger 来说,有状态的 job 不能被并行执行,只有上一次触发的任务被执行完之后,才能触发下一次执行。所有我自己理解为串行的顺序执行(自己怎么好记怎么理解 哈哈)

无状态:无状态任务一般指可以并发的任务,即任务之间是独立的,不会互相干扰。就是各自干各自的。

数据库概貌:

首先上一下sql脚本下载地址:sql数据库rar文件下载

表结构瞅一瞅:

下面是表代表的大致意思吧:

表名

描述

QRTZ_BLOB_TRIGGERS

作为 Blob 类型存储(用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型,JobStore 并不知道如何存储实例的时候)

QRTZ_CALENDARS

以 Blob 类型存储 Quartz 的 Calendar 信息

QRTZ_CRON_TRIGGERS

存储 Cron Trigger,包括 Cron 表达式和时区信息

QRTZ_FIRED_TRIGGERS

存储与已触发的 Trigger 相关的状态信息,以及相联 Job 的执行信息

QRTZ_JOB_DETAILS

存储每一个已配置的 Job 的详细信息

QRTZ_LOCKS

存储程序的非观锁的信息(假如使用了悲观锁)

QRTZ_PAUSED_TRIGGER_GRPS

存储已暂停的 Trigger 组的信息

QRTZ_SCHEDULER_STATE

存储少量的有关 Scheduler 的状态信息,和别的 Scheduler 实例(假如是用于一个集群中)

QRTZ_SIMPLE_TRIGGERS

存储简单的 Trigger,包括重复次数,间隔,以及已触的次数

QRTZ_SIMPROP_TRIGGERS

 

QRTZ_TRIGGERS

存储已配置的 Trigger 的信息

代码部分:

工具都有了那就干活吧,既然我上面说了任务分为有状态和无状态,那正好借这个例子一起给介绍一下。首先还是我们的老朋友任务的创建:

这是一个无状态任务

  1. public class ServerJob : IJob
  2. {
  3. private const string Count = "count";
  4. public virtual void Execute(IJobExecutionContext context)
  5. {
  6. JobKey jobKey = context.JobDetail.Key;
  7. try
  8. {
  9. // 如果任务是恢复的任务的话
  10. if (context.Recovering)
  11. {
  12. WritTxt.WriteFile("serversql", jobKey+":恢复打印");
  13. }
  14. else
  15. {
  16. WritTxt.WriteFile("serversql", jobKey+":启动打印");
  17. }
  18. JobDataMap data = context.JobDetail.JobDataMap;
  19. int count;
  20. if (data.ContainsKey(Count))
  21. {
  22. count = data.GetInt(Count);
  23. }
  24. else
  25. {
  26. count = ;
  27. }
  28. count++;
  29. data.Put(Count, count);
  30.  
  31. WritTxt.WriteFile("serversql", string.Format("结束: {0} done at {1}\n 累计数 #{2}", jobKey, DateTime.Now.ToString("r"), count));
  32. }
  33. catch (Exception ex)
  34. {
  35.  
  36. }
  37. }
  38. }

下面是一个有状态任务,因为本人比较懒所有就不写新任务了,直接继承了无状态任务事件。

  1. [PersistJobDataAfterExecution] //代表当前任务是否有状态
  2. [DisallowConcurrentExecution]//代表任务不允许并发
  3. public class ServerJobState : ServerJob
  4. {
  5. }

下面就是我们要说的重点了;数据库配置

只需要在实例化调度器前把我们的数据库配置传进去就好了。

  1. /// <summary>
  2. /// 持久化属性
  3. /// </summary>
  4. NameValueCollection properties = new NameValueCollection();
  5. public ExampleServer()
  6. {
  7. properties["quartz.scheduler.instanceName"] = "TestScheduler";
  8. properties["quartz.scheduler.instanceId"] = "instance_one";
  9. properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
  10. properties["quartz.threadPool.threadCount"] = "";
  11. properties["quartz.threadPool.threadPriority"] = "Normal";
  12. properties["quartz.jobStore.misfireThreshold"] = "";
  13. properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz";
  14. properties["quartz.jobStore.useProperties"] = "false";
  15. properties["quartz.jobStore.dataSource"] = "default";
  16. properties["quartz.jobStore.tablePrefix"] = "QRTZ_";
  17. properties["quartz.jobStore.clustered"] = "true";
  18. properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz";
  19.  
  20. properties["quartz.dataSource.default.connectionString"] = "Server=(local);Database=quartz;Trusted_Connection=True;";
  21. properties["quartz.dataSource.default.provider"] = "SqlServer-20";
  22.  
  23. // First we must get a reference to a scheduler
  24. ISchedulerFactory sf = new StdSchedulerFactory(properties);
  25. Scheduler = sf.GetScheduler();
  26. }

然后就是运行测试了,这里我用了不同的形式返回了调度器和调度工厂。这样子也挺好用的,可以把以前的那种方法改成这种。

  1. /// <summary>
  2. /// 调度工厂
  3. /// </summary>
  4. private static StdSchedulerFactory SchedulerFactory { get; set; }
  5.  
  6. /// <summary>
  7. /// 调度接口
  8. /// </summary>
  9. private static IScheduler Scheduler { get; set; }
  10.  
  11. #region 0.测试
  12. public void Run()
  13. {
  14. string schedId = Scheduler.SchedulerInstanceId;
  15. IJobDetail job = JobBuilder.Create<ServerJob>()
  16. .WithIdentity("ServerJob", schedId)
  17. .RequestRecovery()
  18. .Build();
  19.  
  20. ITrigger trigger = TriggerBuilder.Create()
  21. .WithIdentity("serverTrigger", schedId)
  22. .WithCronSchedule("0/10 * * * * ?") //5秒执行一次
  23. .Build();
  24. //已存在就不重复添加
  25. try
  26. {
  27. Scheduler.ScheduleJob(job, trigger);
  28. }
  29. catch (Exception ex)
  30. {
  31.  
  32. }
  33. IJobDetail jobState = JobBuilder.Create<ServerJobState>()
  34. .WithIdentity("ServerJobSatte", schedId)
  35. .RequestRecovery()
  36. .Build();
  37.  
  38. ITrigger triggerState = TriggerBuilder.Create()
  39. .WithIdentity("serverTriggerSatte", schedId)
  40. .WithCronSchedule("0/10 * * * * ?") //5秒执行一次
  41. .Build();
  42. //已存在就不重复添加
  43. try
  44. {
  45. Scheduler.ScheduleJob(jobState, triggerState);
  46. }
  47. catch (Exception ex)
  48. {
  49.  
  50. }
  51. //启动
  52. Scheduler.Start();
  53.  
  54. }
  55. #endregion

最后就是大结局了,让我们看下运行结果吧:

【Quartz】持久化到数据库【五】的更多相关文章

  1. quartz 持久化 数据库表

    此处只包括配置数据库操作 quartz 持久化数据库表格字段解释建表,SQL语句在dbTables文件夹中可以找到,介绍下我们开发主要使用到的表: (版本不一样,可能数据库表也不一样,这里使用2.2. ...

  2. SpringBoot2.x集成Quartz实现定时任务管理(持久化到数据库)

    1. Quartz简介   Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目.   Quartz是一个完全由Java编写的开源作业调度框架,为在Java应 ...

  3. SpringBoot整合Quartz定时任务(持久化到数据库)

    背景 最近在做项目,项目中有个需求:需要使用定时任务,这个定时任务需要即时生效.查看Quartz官网之后发现:Quartz提供两种基本作业存储类型: RAMJobStore :RAM也就是内存,默认情 ...

  4. Spring Quartz 持久化解决方案

    Quartz是实现了序列化接口的,包括接口,所以可以使用标准方式序列化到数据库. 而Spring2.5.6在集成Quartz时却未能考虑持久化问题. Spring对JobDetail进行了封装,却未实 ...

  5. quartz定时任务(数据库需要的表)

    Quartz将Job保存在数据库中所需表的说明 QRTZ_CALENDARS 以 Blob 类型存储 Quartz 的 Calendar 信息 QRTZ_CRON_TRIGGERS 存储 Cron T ...

  6. Jena将owl文件持久化到数据库中

    package cn.edu.shu.db; import java.io.File; import java.io.FileInputStream; import java.io.IOExcepti ...

  7. ActiveMQ(4) ActiveMQ JDBC 持久化 Mysql 数据库

    ActiveMQ 消息持久化机制: ActiveMQ 消息的持久化机制有 JDBC.AMQ.KahaDB 和 LevelDB,其中本示例版本(5.15.2)默认机制为 KahaDB.无论哪种持久化机制 ...

  8. Quartz持久化到mongodb

    springboot中集成quzrtz ,持久到mongodb 1.pom引用 <?xml version="1.0" encoding="UTF-8"? ...

  9. identity4 系列————持久化配置篇[五]

    前言 上面已经介绍了3个例子了,并且介绍了如何去使用identity. 但是在前面的例子中,我们使用的都是在内存中操作,那么正式上线可能需要持久到数据库中. 这里值得说明的是,并不一定一定要持久化到数 ...

随机推荐

  1. Java深拷贝浅拷贝

    首先,Java中常用的拷贝操作有三个,operator = .拷贝构造函数 和 clone()方法.由于Java不支持运算符重载,我们无法在自己的自定义类型中定义operator=.拷贝构造函数大家应 ...

  2. How tomcat works 读书笔记十七 启动tomcat 上

    一路跋山涉水,这是最后一章了. 关于tomcat的启动,有两个类,一个是Catalina类,一个是Bootstrap类. 理论上,两个类可以和到一起,但是为了支持多种运行模式,又把他们分开了. 为了让 ...

  3. MongoDB之整库备份还原单表collection备份还原

    MongoDB之整库备份还原单表collection备份还原 cd D:\MongoDB\bin 1整库备份: mongodump -h dbhost -d dbname -o dbdirectory ...

  4. 基于异步队列的生产者消费者C#并发设计

    继上文<<基于阻塞队列的生产者消费者C#并发设计>>的并发队列版本的并发设计,原文code是基于<<.Net中的并行编程-4.实现高性能异步队列>>修改 ...

  5. 解读Raft(四 成员变更)

    将成员变更纳入到算法中是Raft易于应用到实践中的关键,相对于Paxos,它给出了明确的变更过程(实践的基础,任何现实的系统中都会遇到因为硬件故障等原因引起的节点变更的操作). 显然,我们可以通过sh ...

  6. mini-tabs多个div并列,并可隐藏某个div

    <div class="mini-tabs" activeIndex="0" id="tabs"> <div title= ...

  7. ORACLE分页SQL语句(转载)

    1.根据ROWID来分select * from t_xiaoxi where rowid in(select rid from (select rownum rn,rid from(select r ...

  8. 【转】H.264中的NAL技术

    NAL技术 1.NAL概述 NAL全称Network Abstract Layer,即网络抽象层.在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面 ...

  9. Mac下通过brew安装指定版本的nodejs

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px "PingFang SC Semibold"; color: #2c303 ...

  10. Kali Linux Live USB初始化+使用日记

    1.Live USB制作官方guide:Making a Kali Bootable USB Drive:https://docs.kali.org/downloading/kali-linux-li ...