为集群配置Quartz的JDBCJobStore
JDBCJobStore is also aptly named - it keeps all of its data in a database via JDBC. Because of this it is a bit more complicated to configure than RAMJobStore, and it also is not as fast. However, the performance draw-back is not terribly bad, especially if you build the database tables with indexes on the primary keys. On a 800MHz Windoz box running a Quartz application utilizing Oracle running on a not-so-new Solaris box, the time to retreive and update a firing trigger and its associated job has been measured at about 15 milliseconds.
JDBCJobStore works with nearly any database, it has been used widely with Oracle, MySQL, MS SQLServer2000, HSQLDB, PostreSQL and DB2. To use JDBCJobStore, you must first create a set of database tables for Quartz to use. You can find table-creation SQL scripts in the "docs/dbTables" directory of the Quartz distribution. If there is not already a script for your database type, just look at one of the existing ones, and modify it in any way necessary for your DB. One thing to note is that in these scripts, all the the tables start with the prefix "QRTZ_" (such as the tables "QRTZ_TRIGGERS", and "QRTZ_JOB_DETAIL"). This prefix can actually be anything you'd like, as long as you inform JDBCJobStore what the prefix is (in your Quartz properties). Using different prefixes may be useful for creating multiple sets of tables, for multiple scheduler instances, within the same database.
Once you've got the tables created, you have one more major decision to make before configuring and firing up JDBCJobStore. You need to decide what type of transactions your application needs. If you don't need to tie your scheduling commands (such as adding and removing triggers) to other transactions, then you can let Quartz manage the transaction by using JobStoreTX as your JobStore (this is the most common selection).
If you need Quartz to work along with other transactions (i.e. within a J2EE application server), then you should use JobStoreCMT - in which case Quartz will let the app server container manage the transactions.
The last piece of the puzzle is setting up a DataSource from which JDBCJobStore can get connections to your database. DataSources are defined in your Quartz properties using one of a few different approaches. One approach is to have Quartz create and manage the DataSource itself - by providing all of the connection information for the database. Another approach is to have Quartz use a DataSource that is managed by an application server that Quartz is running inside of - by providing JDBCJobStore the JNDI name of the DataSource. For details on the properties, consult the example config files in the "docs/config" folder.
To use JDBCJobStore (and assuming you're using StdSchedulerFactory) you first need to set the JobStore class property of your Quartz configuration to be either org.quartz.impl.jdbcjobstore.JobStoreTX or org.quartz.impl.jdbcjobstore.JobStoreCMT - depending on the selection you made based on the explanations in the above few paragraphs.
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
Next, you need to select a DriverDelegate for the JobStore to use. The DriverDelegate is responsible for doing any JDBC work that may be needed for your specific database. StdJDBCDelegate is a delegate that uses "vanilla" JDBC code (and SQL statements) to do its work. If there isn't another delegate made specifically for your database, try using this delgate - we've only made database-specific delegates for databases that we've found problems using StdJDBCDelegate with (which seems to be most . Other delegates can be found in the "org.quartz.impl.jdbcjobstore" package, or in its sub-packages. Other delegates include DB2v6Delegate (for DB2 version 6 and earlier), HSQLDBDelegate (for HSQLDB), MSSQLDelegate (for microsoft SQLServer 2000), PostgreSQLDelegate (for PostgreSQL 7.x), WeblogicDelegate (for using JDBC drivers made by Weblogic), and OracleDelegate (for using Oracle 8i and 9i).
Once you've selected your delegate, set its class name as the delegate for JDBCJobStore to use.
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
Next, you need to inform the JobStore what table prefix (discussed above) you are using.
org.quartz.jobStore.tablePrefix = QRTZ_
And finally, you need to set which DataSource should be used by the JobStore. The named DataSource must also be defined in your Quartz properties. In this case, we're specifying that Quartz should use the DataSource name "myDS" (that is defined elsewhere in the configuration properties).
org.quartz.jobStore.dataSource = myDS
If your Scheduler is very busy (i.e. nearly always executing the same number of jobs as the size of the thread pool, then you should probably set the number of connections in the DataSource to be the about the size of the thread pool + 1. |
The "org.quartz.jobStore.useProperties" config parameter can be set to "true" (defaults to false) in order to instruct JDBCJobStore that all values in JobDataMaps will be Strings, and therefore can be stored as name-value pairs, rather than storing more complex objects in their serialized form in the BLOB column. This is much safer in the long term, as you avoid the class versioning issues that there are with serializing your non-String classes into a BLOB. |