# 作业存储JobStore
作业存储(JobStore)负责跟踪您提供给调度器的所有“工作数据”:作业、触发器、日历等。为Quartz调度器实例选择合适的作业存储是一个重要步骤。幸运的是,一旦你了解了它们之间的区别,选择应该是非常容易的。在向调度器工厂提供的属性文件(或对象)中声明调度器应使用的作业存储(及其配置设置),调度器工厂用于生成调度器实例。
注意
永远不要在代码中直接使用JobStore实例。出于某种原因,许多人试图这样做。JobStore用于Quartz本身的幕后使用。您必须告诉Quartz(通过配置)要使用哪个JobStore,但然后您应该只在代码中使用调度器接口。
# RAMJobStore
RAMJobStore
是使用最简单的作业存储,也是性能最高的(以CPU时间计算)。RAMJobStore
的名字很明显:它将所有数据保存在RAM中。这就是为什么它的速度如此之快,也是为什么它的配置如此简单。缺点是,当应用程序结束(或崩溃)时,所有调度信息都会丢失——这意味着RAMJobStore
无法遵守作业和触发器的“非波动性”设置。对于某些应用程序来说,这是可以接受的,甚至是期望的行为,但对于其他应用程序,这可能是灾难性的。
要使用RAMJobStore
(假设您使用的是StdSchedulerFactory
),只需将类名org.quartz.simpl.RAMJobStore
指定为用于配置Quartz的JobStore类属性:
配置Quartz以使用RAMJobStore:
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
您无需担心其他设置。
# JDBCJobStore
JDBCJobStore
的名称也很恰当——它通过JDBC将所有数据保存在数据库中。因此,它的配置比RAMJobStore
更复杂,而且速度也不如RAMJobStore
快。然而,性能下降并不是很糟糕,尤其是在主键上使用索引构建数据库表时。在相当现代化的一组具有良好LAN(在调度器和数据库之间)的机器上,检索和更新触发的时间通常少于10毫秒。
JDBCJobStore
几乎可以与任何数据库一起使用,它已广泛用于Oracle、PostgreSQL、MySQL、MS SQL Server、HSQLDB和DB2。要使用JDBCJobStore
,必须首先创建一组供Quartz使用的数据库表。您可以在Quartz发行版的“docs/dbTables”目录中找到表创建SQL脚本。如果您的数据库类型还没有脚本,只需查看其中一个现有的脚本,然后以您的数据库所需的任何方式对其进行修改。需要注意的一点是,在这些脚本中,所有表都以前缀“QRTZ_”开头(例如表“QRTZ_TRIGGERS”和“QRTZ_JOB_DETAIL”)。这个前缀实际上可以是任何你想要的,只要你告诉JDBCJobStore
前缀是什么(在你的Quartz属性中)。对于在同一数据库中为多个调度程序实例创建多组表,使用不同的前缀可能很有用。
一旦创建了表,在配置和启动JDBCJobStore
之前还有一个重要的决定要做。您需要决定应用程序需要什么类型的事务。如果您不需要将调度命令(例如添加和删除触发器)绑定到其他事务,那么您可以让Quartz使用JobStoreTX
作为作业存储来管理事务(这是最常见的选择)。
如果您需要Quartz与其他事务一起工作(即在J2EE应用程序服务器中),那么您应该使用JobStoreCMT
——在这种情况下,Quartz将让应用程序服务器容器管理事务。
最后一个难题是设置一个DataSource
,JDBCJobStore
可以从中获取到数据库的连接。使用几种不同的方法之一在Quartz属性中定义数据源。一种方法是让Quartz创建和管理DataSource
本身——通过为数据库提供所有连接信息。另一种方法是让Quartz使用一个DataSource
,该DataSource
由Quartz在其中运行的应用程序服务器管理,方法是提供JDBCJobStore DataSource
的JNDI名称。有关属性的详细信息,请参阅“docs/config”文件夹中的示例配置文件。
要使用JDBCJobStore
(假设您使用的是StdSchedulerFactory
),首先需要将Quartz配置的JobStore类属性设置为org.Quartz.impl.JDBCJobStore.JobStoreTX
或org.Quartz.impl.jdbc JobStore.Job StoreCMT
,具体取决于您根据上面几段中的解释所做的选择。
配置Quartz以使用JobStoreTx:
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
接下来,您需要为作业存储选择要使用的驱动代理(DriverDelegate
)。驱动代理负责执行特定数据库可能需要的任何JDBC工作。StdJDBCDelegate
是一个使用“普通”JDBC代码(和SQL语句)完成工作的委托。如果没有专门为您的数据库生成的其他委托,请尝试使用此代理——我们只为使用StdJDBCDelegate
时发现问题的数据库生成了特定于数据库的委托(这似乎是最常见的!)。其他代理可以在“org.quartz.impl.jdbjobstore”包或其子包中找到。其他代理包括DB2v6Delegate
(适用于DB2版本6和更早版本)、HSQLDBDelegate
(适用于HSQLDB)、MSSQLDelegae
(适用于Microsoft SQLServer)、PostgreSQLDelegate
(适用于PostgreSQL)、WeblogicDelegate
。
选择代理后,将其类名设置为JDBC作业存储要使用的委托。
配置JDBC作业存储以使用驱动代理:
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
接下来,您需要通知作业存储您正在使用的表前缀(如上所述)。
使用表前缀配置JDBC作业存储:
org.quartz.jobStore.tablePrefix = QRTZ_
最后,您需要设置作业存储应该使用哪个数据源。命名的数据源也必须在Quartz属性中定义。在本例中,我们指定Quartz应使用数据源名称“myDS”(在配置属性的其他地方定义)。
使用要使用的数据源的名称配置JDBC作业存储:
org.quartz.jobStore.dataSource = myDS
如果调度器忙(即几乎总是执行与线程池大小相同数量的作业),那么您可能应该将数据源中的连接数设置为大约线程池大小+2。
“org.quartz.jobStore.useProperties”配置参数可以设置为“true”(默认为false),以便指示
JDBCJobStore
,JobDataMaps
中的所有值都将是字符串,因此可以存储为名称-值对,而不是将更复杂的对象以序列化形式存储在BLOB列中。从长远来看,这要安全得多,因为您可以避免将非String类序列化为BLOB时出现的类版本控制问题。
# TerracottaJobStore
TerracottJobStore
提供了一种在不使用数据库的情况下扩展和健壮性的方法。这意味着您的数据库可以不受Quartz的加载,而是可以为应用程序的其余部分保存所有资源。
TerracottaJobStore
可以集群或非集群运行,无论哪种情况,它都为您的作业数据提供了一种存储介质,在应用程序重新启动期间保持不变,因为数据存储在Terracotta服务器中。它的性能比通过JDBCJobStore
使用数据库要好得多(大约好一个数量级),但比RAMJobStore
慢得多。
要使用TerracottJobStor
e(假设您使用的是StdSchedulerFactory
),只需指定类名org.quartz.jobStore.class = org.terracotta.quartz.TerracottaJobStore作为JobStore类属性,用于配置Quartz,并添加一行额外的配置以指定Terracotta服务器的位置:
配置Quartz以使用TerracottJobStore:
org.quartz.jobStore.class = org.terracotta.quartz.TerracottaJobStore
org.quartz.jobStore.tcConfigUrl = localhost:9510
有关Job存储和Terracotta的更多信息,请访问:http://www.terracotta.org/quartz (opens new window)

微信公众号

QQ交流群
如若发现错误,诚心感谢反馈。
愿你倾心相念,愿你学有所成。
愿你朝华相顾,愿你前程似锦。