Quartz.NET - 教程 9: 作业存储

译者注:
目录在这 Quartz.NET 3.x 教程
原文在这 Lesson 9: JobStores

作业存储负责跟踪你提供给调度程序的所有 "工作数据": 作业, 触发器, 日历, 等. 给调度程序选择一个合适的 IJobStore 实现是非常重要的一步. 幸运的是, 一旦你理解了她们之间的区别选择是非常容易的. 你可以在你提供给调度工厂的属性文件 (或对象) 中声明调度程序应该使用哪个 JobStore (以及存储配置) 以便生成调度程序实例.

切勿在代码中直接使用 JobStore 实例. 出于某些原因许多人试图这样做. JobStore 用于 Quartz 本身的幕后使用. 你必须告诉 Quartz (通过配置) 使用哪个 JobStore. 但是在你的代码中你应该只使用 Scheduler 接口.

RAMJobStore

RAMJobStore 是最简单的 JobStore, 也是性能最好的 (就 CPU 时间而言). 顾名思义: RAMJobStore 把所有数据保存到 RAM 中. 这也是她闪电般快速, 以及配置如此简单的原因. 缺点是当你的应用程序结束 (或崩溃) 时所有调度信息会丢失 - 这意味着 RAMJobStore 无法遵守对作业和触发器的 "非易失性" 设置. 对于某些应用程序而言这是可以接受的 - 亦或就是所需的行为, 但是对于其他应用程序而言, 这可能是灾难.

配置 Quartz 使用 RAMJobStore

quartz.jobStore.type = Quartz.Simpl.RAMJobStore, Quartz

要使用 RAMJobStore (并假设你使用了 StdSchedulerFactory) 你不需要做任何特殊的事情. Quartz.NET 使用 RAMJobStore 作为 JobStore 实现的默认配置.

ADO.NET Job Store (AdoJobStore)

AdoJobStore 的命名也很巧妙 - 她通过 ADO.NET 将所有数据保存到数据库中. 因此配置会比 RAMJobStore 复杂一些, 也没那么快速. 但是, 性能退化的也没那么严重, 尤其是当你构建数据表并在主键上使用了索引.

要使用 AdoJobStore, 您必须先创建一组数据表以供 Quartz.NET 使用. 您可以在 Quartz.NET 发布的 "database/dbtables" 目录下找到表创建 SQL 脚本. 如果没有您需要的数据库类型的脚本, 只需要查看一个现有的脚本, 并以您数据库所需的方式进行修改调整. 需要注意的一点是在这些脚本中, 所有表都以前缀 "QRTZ_" 开头 (例如表 “QRTZ_TRIGGERS”, 和 “QRTZ_JOB_DETAIL”). 这个前缀实际上可以是您想要的任何东西, 只要您告知 Quartz.NET 这个前缀是什么 (在您的 Quartz.NET 属性中). 对于同一数据库, 多个调度程序实例, 使用不同前缀可能对创建多组表很有用.

目前作业存储内部实现的唯一选项是 JobStoreTX 她自己创建事务. 这跟还可以使用 J2EE 容器托管事务的 JobStoreCMT 的 Java 版本的 Quart 不同.

最后一个难题是建立一个数据源以便 AdoJobStore 可以从中获取您数据库的链接. 数据源定义在您的 Quartz.NET 属性中. 数据源信息包含了连接字符串以及 ADO.NET 委托信息.

配置 Quartz 使用 JobStoreTX

quartz.jobStore.type = Quartz.Impl.AdoJobStore.JobStoreTX, Quartz

接下来, 您需要选择一个 IDriverDelegate 实现以供 JobStore 使用. DriverDelegate 负责执行特定数据库可能需要的任何 ADO.NET 工作. SdtAdoDelegate 是一个使用 "普通" ADO.NET 代码 (就是 SQL 语句) 来工作的委托. 如果没有为您数据库专门创建的委托, 请尝试使用这个委托 - 特定委托通常具有更好的性能或解决数据库特定问题的方案. 其他委托可以在 "Quartz.Impl.AdoJobStore" 命名空间, 或在其他子命名空间中找到.

注意: Quartz.NET 会发出警告如果您使用默认的 StdAdoDelegate 做为委托时存在性能不足当您有选多选择器以供选择时. 特殊的委托有特殊的 SQL 来限制结果集长度 (SQLServerDelegate 使用 TOP n, PostgreSQLDelegate LIMIT n, OracleDelegate ROWCOUNT() <= n 等.).

一旦您选择了委托, 应该将其类名做为委托值以供 AdoJobStore 使用.

配置 AdoJobStore 使用驱动器委托

quartz.jobStore.driverDelegateType = Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz

接下来, 你需要告知 JobStore 你正在使用的表前缀是什么 (前面提到过).

配置 AdoJobStore 使用表前缀

quartz.jobStore.tablePrefix = QRTZ_

最后, 你需要设置 JobStore 应该使用哪个数据源. 数据源的命名也必须定义在您的 Quartz.NET 属性中. 在这种情况下, 我们指定 Quartz 应该使用的数据源名称为 "myDS" (在配置属性的其他地方定义).

配置 AdoJobStore 使用的数据源名称

quartz.jobStore.dataSource = myDS

One last thing that is needed for the configuration is to set data source connection string information and database provider. Connection string is the standard ADO.NET connection which is driver specific. Database provider is an abstraction of database drivers to create loose coupling between database drivers and Quartz.

设置数据源连接字符串和数据库提供器

 quartz.dataSource.myDS.connectionString = Server=localhost;Database=quartz;Uid=quartznet;Pwd=quartznet
 quartz.dataSource.myDS.provider = MySql

目前支持一下数据库提供器:

  • SqlServer - SQL Server driver for .NET Framework 2.0
  • OracleODP - Oracle’s Oracle Driver
  • OracleODPManaged - Oracle’s managed driver for Oracle 11
  • MySql - MySQL Connector/.NET
  • SQLite - SQLite ADO.NET Provider
  • SQLite-Microsoft - Microsoft SQLite ADO.NET Provider
  • Firebird - Firebird ADO.NET Provider
  • Npgsql - PostgreSQL Npgsql

您可以也应该使用最新版本的驱动程序如果新的可用, 只需创建一个程序集绑定重定向

如果您的调度程序非常繁忙 (即几乎总是执行与线程池大小相同的作业数), 那么您可能应该将数据源中的连接数设置为线程池大小 + 1. 这通常在 ADO.NET 连接字符串中配置 - 详情请参阅您的驱动程序实现.

可以将 "quartz.jobStore.useProperties" 配置参数设置为 "true" (默认为 false) 来指定 AdoJobStore JobDataMaps 的所有值为字符串. 因此可以做为 名称-值对来存储, 而不是将更复杂的对象以序列化的形式存储在 BLOB 列中. 从长远来看, 您可以规避将非-字符类序列化为 BLOB 时出现的类版本问题.

配置 AdoJobStore 使用字符串做为 JobDataMap 的值 (建议)

quartz.jobStore.useProperties = true
posted @ 2019-04-04 14:16  taadis  阅读(671)  评论(0编辑  收藏  举报