The first persistent JobStore that we discuss is called JobStoreTX. The "TX" in the name stands for "transaction." As we stated earlier, the JobStoreTX is designed to be used in an environment in which you want Quartz to manage the transactions. For example, if you are building a J2SE application and are not using an application server such as WebLogic or JBoss, JobStoreTX would be the right choice for a persistent JobStore.
In the last section, you saw how easy it is to configure the RAMJobStore. We mentioned that one of the advantages to the RAMJobStore is its simple configuration. We've already discussed what has to be done to the database to get it ready; we now discuss what's needed to configure the Quartz application for a JDBC JobStore.
Configuring the JobStoreTX
To tell the Quartz runtime environment that you want to use a JobStore other than the default RAMJobStore, you must configure several properties. It doesn't matter what order you do them in, but they all must be done before you run the application for the first time.
Setting the JobStore Property
To inform the Scheduler that JobStoreTX should be used, you must add the following line to the quartz.properties file:
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
Be sure to remove the RAMJobStore line (if present) when switching to the JobStoreTX.
Configuring the Driver Delegate
In the same way that the JDBC API relies on a JDBC driver designed specifically for a database platform, Quartz relies on a DriverDelegate to communicate with a given database. As the name implies, database calls from the Scheduler to the JobStore are delegated to a preconfigured DriverDelegate instance. The delegate is responsible for all communications with the JDBC driver and, thus, the database.
All DriverDelegate classes extend the org.quartz.impl.jdbcjobstore.StdDriverDelegate class. The StdDriverDelegate has base functionality that all delegates, regardless of platform, can use. However, there is enough difference between some of these database platforms that a specialized delegate needs to be created for some platforms. Table 6.2 lists the specialized delegates.
Database Platform |
Quartz Delegate Class |
---|---|
Cloudscape/Derby |
org.quartz.impl.jdbcjobstore.CloudscapeDelegate |
DB2 (version 6.x) |
org.quartz.impl.jdbcjobstore.DB2v6Delegate |
DB2 (version 7.x) |
org.quartz.impl.jdbcjobstore.DB2v7Delegate |
DB2 (version 8.x) |
org.quartz.impl.jdbcjobstore.DB2v8Delegate |
HSQLDB |
org.quartz.impl.jdbcjobstore.PostgreSQLDelegate |
MS SQL Server |
org.quartz.impl.jdbcjobstore.MSSQLDelegate |
Pointbase |
org.quartz.impl.jdbcjobstore.PointbaseDelegate |
PostgreSQL |
org.quartz.impl.jdbcjobstore.PostgreSQLDelegate |
(WebLogic JDBC Driver) |
org.quartz.impl.jdbcjobstore.WebLogicDelegate |
(WebLogic 8.1 with Oracle) |
org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate |
Oracle |
org.quartz.impl.jdbcjobstore.oracle.OracleDelegate |
After you determine which delegate you need based on your database platform, you need to add the following to the quartz.properties file:
org.quartz.jobStore.driverDelegateClass=
As an example, if you are using MS SQL Server as your database platform, you would need to add the following to the properties file:
org.quartz.jobStore.driverDelegateClass= org.quartz.impl.jdbcjobstore.MSSQLDelegate
Configuring the Database Table Prefix
Back when we first discussed the database tables for Quartz, we mentioned that all the tables had the prefix QRTZ_ added to them. Under certain circumstances, you might need to create multiple sets of Quartz database tables. In that situation, you would need to change the prefix for each set.
The prefixes for the table names are configured in the quartz.properties file using the property org.quartz.jobStore.tablePrefix. To change the prefix, just set the property to a different value:
org.quartz.jobStore.tablePrefix = SCHEDULER2_
Make sure the table names all start with this prefix.
Table 6.3 shows the set of properties that can be used to tune the JobStoreTX.
Property |
Default |
---|---|
org.quartz.jobStore.driverDelegateClass |
|
Description: Driver delegates understand the particular dialects of various database systems. |
|
org.quartz.jobStore.dataSource |
|
Description: This is the name used in the DataSource configuration section of the quartz.properties file. |
|
org.quartz.jobStore.tablePrefix |
QRTZ_ |
Description: This is the prefix given to the set of database tables for this Scheduler. Schedulers can use different tables from the same database if the prefixes are different. |
|
org.quartz.jobStore.useProperties |
False |
Description: The "use properties" flag instructs the persistent JobStore that all values in JobDataMaps will be Strings and, therefore, can be stored as name-value pairs instead of storing more complex objects in their serialized form in the BLOB column. This is can be handy because you avoid the class-versioning issues that can arise from serializing your non-String classes into a BLOB. |
|
org.quartz.jobStore.misfireThreshold |
60000 |
Description: The number of milliseconds the Scheduler will tolerate a trigger to pass its next-fire-time before being considered misfired. The default value (if you don't make an entry of this property in your configuration) is 60000 (60 seconds). This is not specific to JDBC-JobStore; it is also a parameter used by RAMJobStore. |
|
org.quartz.jobStore.isClustered |
False |
Description: Set this to true to turn on clustering features. This property must be set to true if you are having multiple instances of Quartz use the same set of database tables. |
|
org.quartz.jobStore.clusterCheckinInterval |
15000 |
Description: Set the frequency (in milliseconds) at which this instance checks in with the other instances of the cluster. This affects the quickness of detecting failed instances. It is used only when isClustered is set to true. |
|
org.quartz.jobStore.maxMisfiresToHandleAtATime |
20 |
Description: This is the maximum number of misfired triggers the JobStore will handle in a given pass. Handling many (more than a couple dozen) at once can cause the database tables to be locked long enough to hamper the performance of firing other (not yet misfired) triggers. |
|
org.quartz.jobStore.dontSetAutoCommitFalse |
False |
Description: Setting this parameter to true tells Quartz not to call setAutoCommit(false) on connections obtained from the DataSource(s). This can be helpful in a few situations, such as if you have a driver that complains if it is called when it is already off. This property defaults to false because most drivers require that setAutoCommit(false) be called. |
|
org.quartz.jobStore.selectWithLockSQL |
SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE |
Description: This must be a SQL string that selects a row in the LOCKS table and places a lock on the row. If it is not set, the default is SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE, which works for most databases. The {0} is replaced during runtime with the TABLE_PREFIX that you configured earlier. |
|
org.quartz.jobStore.txIsolationLevelSerializable |
False |
Description: A value of true tells Quartz (when using JobStoreTX or CMT) to call setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE) on JDBC connections. This can be helpful to prevent lock timeouts with some databases under high load and long-lasting transactions. |
Scheduling in the Enterprise
Getting Started with Quartz
Hello, Quartz
Scheduling Jobs
Cron Triggers and More
JobStores and Persistence
Implementing Quartz Listeners
Using Quartz Plug-Ins
Using Quartz Remotely
Using Quartz with J2EE
Clustering Quartz
Quartz Cookbook
Quartz and Web Applications
Using Quartz with Workflow
Appendix A. Quartz Configuration Reference