CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-quartz-scheduler--quartz

Quartz Enterprise Job Scheduler - A richly featured, open source job scheduling library that can be integrated within virtually any Java application

Pending
Overview
Eval results
Files

persistence-storage.mddocs/

Persistence and Storage

Comprehensive data persistence system in Quartz supporting both in-memory and database storage with sophisticated connection pooling, transaction management, and database-specific optimizations. This system provides the foundation for job and trigger persistence, clustering, and enterprise-scale deployments.

Capabilities

JobStore Interface

Base interface for all job and trigger persistence implementations.

/**
 * Interface for storing and retrieving jobs and triggers
 */
interface JobStore {
    /**
     * Initialize the job store
     * @param loadHelper class loading helper
     * @param signaler scheduler signaler for notifications
     * @throws SchedulerConfigException if initialization fails
     */
    void initialize(ClassLoadHelper loadHelper, SchedulerSignaler signaler) throws SchedulerConfigException;
    
    /**
     * Start the job store for use
     * @throws SchedulerException if startup fails
     */
    void schedulerStarted() throws SchedulerException;
    
    /**
     * Shutdown the job store
     */
    void shutdown();
    
    /**
     * Store a job and its associated triggers
     * @param newJob the job to store
     * @param newTriggers triggers associated with the job
     * @param replace whether to replace existing job
     * @throws SchedulerException if storage fails
     */
    void storeJobAndTrigger(JobDetail newJob, OperableTrigger newTrigger) throws SchedulerException;
    
    /**
     * Store a job
     * @param newJob the job to store
     * @param replaceExisting whether to replace existing job
     * @throws SchedulerException if storage fails
     */
    void storeJob(JobDetail newJob, boolean replaceExisting) throws SchedulerException;
    
    /**
     * Store a trigger
     * @param newTrigger the trigger to store
     * @param replaceExisting whether to replace existing trigger
     * @throws SchedulerException if storage fails
     */
    void storeTrigger(OperableTrigger newTrigger, boolean replaceExisting) throws SchedulerException;
    
    /**
     * Remove a job and all its triggers
     * @param jobKey the job key
     * @return true if job was removed
     * @throws SchedulerException if removal fails
     */
    boolean removeJob(JobKey jobKey) throws SchedulerException;
    
    /**
     * Remove a trigger
     * @param triggerKey the trigger key
     * @return true if trigger was removed
     * @throws SchedulerException if removal fails
     */
    boolean removeTrigger(TriggerKey triggerKey) throws SchedulerException;
    
    /**
     * Retrieve a job
     * @param jobKey the job key
     * @return the job detail or null if not found
     * @throws SchedulerException if retrieval fails
     */
    JobDetail retrieveJob(JobKey jobKey) throws SchedulerException;
    
    /**
     * Retrieve a trigger
     * @param triggerKey the trigger key
     * @return the trigger or null if not found
     * @throws SchedulerException if retrieval fails
     */
    OperableTrigger retrieveTrigger(TriggerKey triggerKey) throws SchedulerException;
    
    /**
     * Acquire triggers ready to fire
     * @param noLaterThan maximum fire time
     * @param maxCount maximum number of triggers
     * @param timeWindow time window for acquisition
     * @return list of trigger fire bundles
     * @throws SchedulerException if acquisition fails
     */
    List<OperableTrigger> acquireNextTriggers(long noLaterThan, int maxCount, long timeWindow) throws SchedulerException;
    
    /**
     * Inform job store that triggers have been fired
     * @param triggers the fired triggers
     * @return firing results
     * @throws SchedulerException if operation fails
     */
    List<TriggerFiredResult> triggersFired(List<OperableTrigger> triggers) throws SchedulerException;
    
    /**
     * Check if job store supports persistence
     * @return true if persistent
     */
    boolean supportsPersistence();
    
    /**
     * Check if job store is clustered
     * @return true if clustered
     */
    boolean isClustered();
}

RAMJobStore Class

In-memory job store implementation for single-node, volatile storage.

/**
 * In-memory job store - data is lost when JVM stops
 */
class RAMJobStore implements JobStore {
    /**
     * Create in-memory job store
     */
    RAMJobStore();
    
    /**
     * Set misfire threshold in milliseconds
     * @param misfireThreshold threshold in milliseconds
     */
    void setMisfireThreshold(long misfireThreshold);
    
    /**
     * Get misfire threshold
     * @return misfire threshold in milliseconds
     */
    long getMisfireThreshold();
    
    // Inherits all JobStore methods
    // Data stored in memory - not persistent across restarts
    // Fast performance, no database dependencies
    // Single scheduler instance only
}

JDBC JobStore Classes

Database-backed job stores for persistent, clustered storage.

/**
 * JDBC job store with transaction management
 */
class JobStoreTX extends JobStoreSupport {
    /**
     * Create JDBC job store with transaction management
     */
    JobStoreTX();
    
    // Manages its own database transactions
    // Suitable for standalone applications
    // Uses JobStoreSupport base functionality
}

/**
 * JDBC job store for container-managed transactions
 */
class JobStoreCMT extends JobStoreSupport {
    /**
     * Create JDBC job store for container-managed transactions
     */
    JobStoreCMT();
    
    /**
     * Set whether to use non-managed transactions for locks
     * @param nonManagedTXForLocks true to use non-managed transactions
     */
    void setNonManagedTXForLocks(boolean nonManagedTXForLocks);
    
    // Works with container-managed transactions (CMT)
    // Suitable for J2EE application servers
    // Transaction boundaries managed by container
}

/**
 * Base class for JDBC job store implementations
 */
abstract class JobStoreSupport implements JobStore {
    /**
     * Set the database table prefix
     * @param tablePrefix prefix for all Quartz tables
     */
    void setTablePrefix(String tablePrefix);
    
    /**
     * Set the data source name
     * @param dataSource JNDI name or direct data source name
     */
    void setDataSource(String dataSource);
    
    /**
     * Set the driver delegate class for database-specific SQL
     * @param driverDelegateClass fully qualified class name
     */
    void setDriverDelegateClass(String driverDelegateClass);
    
    /**
     * Set whether job store is clustered
     * @param isClustered true for clustered operation
     */
    void setIsClustered(boolean isClustered);
    
    /**
     * Set cluster check-in interval
     * @param clusterCheckinInterval interval in milliseconds
     */
    void setClusterCheckinInterval(long clusterCheckinInterval);
    
    /**
     * Set maximum misfire threshold
     * @param misfireThreshold threshold in milliseconds
     */
    void setMisfireThreshold(long misfireThreshold);
    
    /**
     * Set whether to use database locks
     * @param useDBLocks true to use database locks
     */
    void setUseDBLocks(boolean useDBLocks);
    
    /**
     * Set lock handler for database locking
     * @param lockHandler lock handler implementation
     */
    void setLockHandler(Semaphore lockHandler);
    
    /**
     * Set whether to acquire triggers within lock
     * @param acquireTriggersWithinLock true to use lock
     */
    void setAcquireTriggersWithinLock(boolean acquireTriggersWithinLock);
}

Database Driver Delegates

Database-specific SQL implementations for optimal performance.

/**
 * Base delegate providing standard SQL operations
 */
class StdJDBCDelegate implements DriverDelegate {
    /**
     * Get the database-specific SQL for operations
     */
    String getSelectNextTriggerToAcquireSQL();
    String getInsertJobDetailSQL();
    String getUpdateJobDetailSQL();
    String getSelectJobDetailSQL();
    String getDeleteJobDetailSQL();
    
    // Additional SQL operation methods
}

/**
 * PostgreSQL-specific optimizations
 */
class PostgreSQLDelegate extends StdJDBCDelegate {
    // PostgreSQL-specific SQL optimizations
    // Better handling of BYTEA columns
    // PostgreSQL-specific lock handling
}

/**
 * Oracle-specific optimizations
 */
class OracleDelegate extends StdJDBCDelegate {
    // Oracle-specific SQL optimizations
    // BLOB/CLOB handling improvements
    // Oracle-specific rowid operations
}

/**
 * MySQL-specific optimizations
 */
class MySQLDelegate extends StdJDBCDelegate {
    // MySQL-specific SQL optimizations
    // MySQL-specific data type handling
}

/**
 * SQL Server-specific optimizations
 */
class MSSQLDelegate extends StdJDBCDelegate {
    // SQL Server-specific SQL optimizations
    // SQL Server-specific lock handling
}

/**
 * DB2-specific optimizations
 */
class DB2v6Delegate extends StdJDBCDelegate {
    // DB2-specific SQL optimizations
}

/**
 * DB2 version 7+ optimizations
 */
class DB2v7Delegate extends DB2v6Delegate {
    // Enhanced DB2 features for version 7+
}

/**
 * CloudscapeDelegate for Apache Derby
 */
class CloudscapeDelegate extends StdJDBCDelegate {
    // Apache Derby / Cloudscape optimizations
}

/**
 * H2 database optimizations
 */
class H2Delegate extends StdJDBCDelegate {
    // H2-specific optimizations
}

/**
 * HSQLDB optimizations
 */
class HSQLDBDelegate extends StdJDBCDelegate {
    // HSQLDB-specific optimizations
}

Connection Pooling

Sophisticated connection pool management for database operations.

/**
 * Interface for providing database connections
 */
interface ConnectionProvider {
    /**
     * Get a database connection
     * @return database connection
     * @throws SQLException if connection cannot be obtained
     */
    Connection getConnection() throws SQLException;
    
    /**
     * Shutdown the connection provider
     * @throws SQLException if shutdown fails
     */
    void shutdown() throws SQLException;
    
    /**
     * Initialize the connection provider
     * @throws SQLException if initialization fails
     */
    void initialize() throws SQLException;
}

/**
 * Interface for pooling connection providers
 */
interface PoolingConnectionProvider extends ConnectionProvider {
    /**
     * Get the current number of connections in the pool
     * @return connection count
     */
    int getPoolSize();
    
    /**
     * Get the maximum pool size
     * @return maximum connections
     */
    int getMaxPoolSize();
    
    /**
     * Get the current number of connections in use
     * @return connections in use
     */
    int getConnectionsInUse();
}

/**
 * C3P0 connection pooling implementation
 */
class C3p0PoolingConnectionProvider implements PoolingConnectionProvider {
    /**
     * Set maximum pool size
     * @param maxPoolSize maximum number of connections
     */
    void setMaxPoolSize(int maxPoolSize);
    
    /**
     * Set minimum pool size
     * @param minPoolSize minimum number of connections
     */
    void setMinPoolSize(int minPoolSize);
    
    /**
     * Set initial pool size
     * @param initialPoolSize initial number of connections
     */
    void setInitialPoolSize(int initialPoolSize);
    
    /**
     * Set maximum idle time for connections
     * @param maxIdleTime idle time in seconds
     */
    void setMaxIdleTime(int maxIdleTime);
    
    /**
     * Set connection test query
     * @param idleConnectionTestPeriod test period in seconds
     */
    void setIdleConnectionTestPeriod(int idleConnectionTestPeriod);
    
    /**
     * Set connection validation query
     * @param validationQuery SQL query for validation
     */
    void setValidationQuery(String validationQuery);
}

/**
 * HikariCP connection pooling implementation
 */
class HikariCpPoolingConnectionProvider implements PoolingConnectionProvider {
    /**
     * Set maximum pool size
     * @param maximumPoolSize maximum number of connections
     */
    void setMaximumPoolSize(int maximumPoolSize);
    
    /**
     * Set minimum idle connections
     * @param minimumIdle minimum idle connections
     */
    void setMinimumIdle(int minimumIdle);
    
    /**
     * Set maximum connection lifetime
     * @param maxLifetime lifetime in milliseconds
     */
    void setMaxLifetime(long maxLifetime);
    
    /**
     * Set connection timeout
     * @param connectionTimeout timeout in milliseconds
     */
    void setConnectionTimeout(long connectionTimeout);
    
    /**
     * Set idle timeout
     * @param idleTimeout timeout in milliseconds
     */
    void setIdleTimeout(long idleTimeout);
    
    /**
     * Set connection test query
     * @param connectionTestQuery SQL query for testing
     */
    void setConnectionTestQuery(String connectionTestQuery);
}

/**
 * JNDI-based connection provider
 */
class JNDIConnectionProvider implements ConnectionProvider {
    /**
     * Set JNDI name for data source lookup
     * @param jndiURL JNDI URL for data source
     */
    void setJndiURL(String jndiURL);
    
    /**
     * Set initial context factory
     * @param java_naming_factory_initial factory class name
     */
    void setJava_naming_factory_initial(String java_naming_factory_initial);
    
    /**
     * Set naming provider URL
     * @param java_naming_provider_url provider URL
     */
    void setJava_naming_provider_url(String java_naming_provider_url);
}

/**
 * Connection manager for managing multiple data sources
 */
class DBConnectionManager {
    /**
     * Get singleton instance
     * @return connection manager instance
     */
    static DBConnectionManager getInstance();
    
    /**
     * Add connection provider
     * @param dataSourceName name of data source
     * @param provider connection provider implementation
     */
    void addConnectionProvider(String dataSourceName, ConnectionProvider provider);
    
    /**
     * Get connection from named data source
     * @param dataSourceName name of data source
     * @return database connection
     * @throws SQLException if connection cannot be obtained
     */
    Connection getConnection(String dataSourceName) throws SQLException;
    
    /**
     * Shutdown all connection providers
     */
    void shutdown();
}

Usage Examples:

// Basic JDBC JobStore Configuration (quartz.properties)
/*
# Use JDBC job store with transaction management
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX

# Database-specific delegate
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate

# Data source configuration
org.quartz.jobStore.dataSource = myDS

# Table prefix (default is QRTZ_)
org.quartz.jobStore.tablePrefix = QRTZ_

# Clustering settings
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000

# Misfire handling
org.quartz.jobStore.misfireThreshold = 60000

# Data source definition
org.quartz.dataSource.myDS.driver = org.postgresql.Driver
org.quartz.dataSource.myDS.URL = jdbc:postgresql://localhost:5432/quartz
org.quartz.dataSource.myDS.user = quartz
org.quartz.dataSource.myDS.password = password
org.quartz.dataSource.myDS.maxConnections = 10
org.quartz.dataSource.myDS.connectionProvider.class = org.quartz.utils.HikariCpPoolingConnectionProvider
*/

// HikariCP Connection Pooling Configuration
/*
# Use HikariCP for connection pooling
org.quartz.dataSource.myDS.connectionProvider.class = org.quartz.utils.HikariCpPoolingConnectionProvider
org.quartz.dataSource.myDS.maximumPoolSize = 20
org.quartz.dataSource.myDS.minimumIdle = 5
org.quartz.dataSource.myDS.maxLifetime = 1800000
org.quartz.dataSource.myDS.connectionTimeout = 30000
org.quartz.dataSource.myDS.idleTimeout = 600000
org.quartz.dataSource.myDS.connectionTestQuery = SELECT 1
*/

// C3P0 Connection Pooling Configuration
/*
# Use C3P0 for connection pooling
org.quartz.dataSource.myDS.connectionProvider.class = org.quartz.utils.C3p0PoolingConnectionProvider
org.quartz.dataSource.myDS.maxPoolSize = 20
org.quartz.dataSource.myDS.minPoolSize = 5
org.quartz.dataSource.myDS.initialPoolSize = 10
org.quartz.dataSource.myDS.maxIdleTime = 300
org.quartz.dataSource.myDS.idleConnectionTestPeriod = 3000
org.quartz.dataSource.myDS.validationQuery = SELECT 1
*/

// JNDI Data Source Configuration
/*
# Use JNDI data source
org.quartz.jobStore.dataSource = myJndiDS
org.quartz.dataSource.myJndiDS.connectionProvider.class = org.quartz.utils.JNDIConnectionProvider
org.quartz.dataSource.myJndiDS.jndiURL = java:comp/env/jdbc/QuartzDS
*/

// Programmatic Configuration
Properties props = new Properties();
props.setProperty("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
props.setProperty("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate");
props.setProperty("org.quartz.jobStore.dataSource", "myDS");
props.setProperty("org.quartz.jobStore.tablePrefix", "QRTZ_");
props.setProperty("org.quartz.jobStore.isClustered", "true");

// Data source properties
props.setProperty("org.quartz.dataSource.myDS.driver", "org.postgresql.Driver");
props.setProperty("org.quartz.dataSource.myDS.URL", "jdbc:postgresql://localhost:5432/quartz");
props.setProperty("org.quartz.dataSource.myDS.user", "quartz");
props.setProperty("org.quartz.dataSource.myDS.password", "password");
props.setProperty("org.quartz.dataSource.myDS.maxConnections", "15");
props.setProperty("org.quartz.dataSource.myDS.connectionProvider.class", 
    "org.quartz.utils.HikariCpPoolingConnectionProvider");

SchedulerFactory factory = new StdSchedulerFactory(props);
Scheduler scheduler = factory.getScheduler();

// Custom Connection Provider
public class CustomConnectionProvider implements PoolingConnectionProvider {
    private HikariDataSource dataSource;
    
    @Override
    public void initialize() throws SQLException {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:postgresql://localhost:5432/quartz");
        config.setUsername("quartz");
        config.setPassword("password");
        config.setMaximumPoolSize(20);
        config.setMinimumIdle(5);
        config.setConnectionTestQuery("SELECT 1");
        
        dataSource = new HikariDataSource(config);
    }
    
    @Override
    public Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    
    @Override
    public void shutdown() throws SQLException {
        if (dataSource != null) {
            dataSource.close();
        }
    }
    
    @Override
    public int getPoolSize() {
        return dataSource.getHikariPoolMXBean().getTotalConnections();
    }
    
    @Override
    public int getMaxPoolSize() {
        return dataSource.getMaximumPoolSize();
    }
    
    @Override
    public int getConnectionsInUse() {
        return dataSource.getHikariPoolMXBean().getActiveConnections();
    }
}

// Database Schema Creation
// Quartz provides SQL scripts for creating required tables:
// - tables_postgres.sql
// - tables_mysql.sql  
// - tables_oracle.sql
// - tables_sqlserver.sql
// - tables_db2.sql
// - tables_h2.sql
// etc.

/*
Example PostgreSQL schema (simplified):
CREATE TABLE qrtz_job_details (
    sched_name VARCHAR(120) NOT NULL,
    job_name VARCHAR(200) NOT NULL,
    job_group VARCHAR(200) NOT NULL,
    description VARCHAR(250) NULL,
    job_class_name VARCHAR(250) NOT NULL,
    is_durable BOOL NOT NULL,
    is_nonconcurrent BOOL NOT NULL,
    is_update_data BOOL NOT NULL,
    requests_recovery BOOL NOT NULL,
    job_data BYTEA NULL,
    PRIMARY KEY (sched_name, job_name, job_group)
);

CREATE TABLE qrtz_triggers (
    sched_name VARCHAR(120) NOT NULL,
    trigger_name VARCHAR(200) NOT NULL,
    trigger_group VARCHAR(200) NOT NULL,
    job_name VARCHAR(200) NOT NULL,
    job_group VARCHAR(200) NOT NULL,
    description VARCHAR(250) NULL,
    next_fire_time BIGINT NULL,
    prev_fire_time BIGINT NULL,
    priority INTEGER NULL,
    trigger_state VARCHAR(16) NOT NULL,
    trigger_type VARCHAR(8) NOT NULL,
    start_time BIGINT NOT NULL,
    end_time BIGINT NULL,
    calendar_name VARCHAR(200) NULL,
    misfire_instr SMALLINT NULL,
    job_data BYTEA NULL,
    PRIMARY KEY (sched_name, trigger_name, trigger_group)
);
*/

// Monitoring Connection Pools
public void monitorConnectionPool(PoolingConnectionProvider provider) {
    System.out.println("Pool Size: " + provider.getPoolSize());
    System.out.println("Max Pool Size: " + provider.getMaxPoolSize());
    System.out.println("Connections In Use: " + provider.getConnectionsInUse());
    System.out.println("Available Connections: " + 
        (provider.getPoolSize() - provider.getConnectionsInUse()));
}

Database Support Matrix

DatabaseDelegate ClassClusteringNotes
PostgreSQLPostgreSQLDelegateYesRecommended for production
MySQLMySQLDelegateYesFull feature support
OracleOracleDelegateYesEnterprise features
SQL ServerMSSQLDelegateYesFull support
DB2DB2v7DelegateYesVersion 7+ recommended
H2H2DelegateLimitedDevelopment/testing
HSQLDBHSQLDBDelegateNoDevelopment only
Apache DerbyCloudscapeDelegateLimitedEmbedded use

Configuration Best Practices

  1. Connection Pooling: Always use connection pooling in production
  2. Database Selection: Use PostgreSQL, MySQL, Oracle, or SQL Server for production
  3. Clustering: Enable clustering for high availability
  4. Table Prefix: Use unique table prefixes for multiple Quartz instances
  5. Monitoring: Monitor connection pool usage and database performance
  6. Backup: Regular backups of job store data for disaster recovery

Install with Tessl CLI

npx tessl i tessl/maven-org-quartz-scheduler--quartz

docs

calendar-management.md

core-scheduling.md

enterprise-features.md

exception-handling.md

index.md

job-management.md

listeners-events.md

matcher-framework.md

persistence-storage.md

schedule-builders.md

trigger-management.md

utilities-helpers.md

tile.json