📄 jobstoretx.java
字号:
/* * Copyright James House (c) 2001-2004 * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: 1. * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. 2. Redistributions in * binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */package org.quartz.impl.jdbcjobstore;import org.quartz.Calendar;import org.quartz.JobDetail;import org.quartz.JobPersistenceException;import org.quartz.ObjectAlreadyExistsException;import org.quartz.SchedulerConfigException;import org.quartz.SchedulerException;import org.quartz.Trigger;import org.quartz.core.SchedulingContext;import org.quartz.spi.ClassLoadHelper;import org.quartz.spi.SchedulerSignaler;import org.quartz.spi.TriggerFiredBundle;import java.sql.Connection;import java.util.List;import java.util.Set;/** * <p> * <code>JobStoreTX</code> is meant to be used in a standalone environment. * Both commit and rollback will be handled by this class. * </p> * * <p> * If you need a <code>{@link org.quartz.spi.JobStore}</code> class to use * within an application-server environment, use <code>{@link * org.quartz.impl.jdbcjobstore.JobStoreCMT}</code> * instead. * </p> * * @author <a href="mailto:jeff@binaryfeed.org">Jeffrey Wescott</a> * @author James House */public class JobStoreTX extends JobStoreSupport { /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Interface. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ public void initialize(ClassLoadHelper loadHelper, SchedulerSignaler signaler) throws SchedulerConfigException { super.initialize(loadHelper, signaler); getLog().info("JobStoreTX initialized."); } //--------------------------------------------------------------------------- // JobStoreSupport methods //--------------------------------------------------------------------------- /** * <p> * Recover any failed or misfired jobs and clean up the data store as * appropriate. * </p> * * @throws JobPersistenceException * if jobs could not be recovered */ protected void recoverJobs() throws JobPersistenceException { Connection conn = getConnection(); boolean transOwner = false; try { getLockHandler().obtainLock(conn, LOCK_TRIGGER_ACCESS); transOwner = true; //getLockHandler().obtainLock(conn, LOCK_JOB_ACCESS); recoverJobs(conn); commitConnection(conn); } catch (JobPersistenceException e) { rollbackConnection(conn); throw e; } finally { releaseLock(conn, LOCK_TRIGGER_ACCESS, transOwner); closeConnection(conn); } } protected void cleanVolatileTriggerAndJobs() throws JobPersistenceException { Connection conn = getConnection(); boolean transOwner = false; try { getLockHandler().obtainLock(conn, LOCK_TRIGGER_ACCESS); transOwner = true; //getLockHandler().obtainLock(conn, LOCK_JOB_ACCESS); cleanVolatileTriggerAndJobs(conn); commitConnection(conn); } catch (JobPersistenceException e) { rollbackConnection(conn); throw e; } finally { releaseLock(conn, LOCK_TRIGGER_ACCESS, transOwner); closeConnection(conn); } } //--------------------------------------------------------------------------- // job / trigger storage methods //--------------------------------------------------------------------------- /** * <p> * Store the given <code>{@link org.quartz.JobDetail}</code> and <code>{@link org.quartz.Trigger}</code>. * </p> * * @param newJob * The <code>JobDetail</code> to be stored. * @param newTrigger * The <code>Trigger</code> to be stored. * @throws ObjectAlreadyExistsException * if a <code>Job</code> with the same name/group already * exists. */ public void storeJobAndTrigger(SchedulingContext ctxt, JobDetail newJob, Trigger newTrigger) throws ObjectAlreadyExistsException, JobPersistenceException { Connection conn = getConnection(); boolean transOwner = false; try { if(isLockOnInsert()) { getLockHandler().obtainLock(conn, LOCK_TRIGGER_ACCESS); transOwner = true; //getLockHandler().obtainLock(conn, LOCK_JOB_ACCESS); } if (newJob.isVolatile() && !newTrigger.isVolatile()) { JobPersistenceException jpe = new JobPersistenceException( "Cannot associate non-volatile " + "trigger with a volatile job!"); jpe.setErrorCode(SchedulerException.ERR_CLIENT_ERROR); throw jpe; } storeJob(conn, ctxt, newJob, false); storeTrigger(conn, ctxt, newTrigger, newJob, false, Constants.STATE_WAITING, false, false); commitConnection(conn); } catch (JobPersistenceException e) { rollbackConnection(conn); throw e; } finally { releaseLock(conn, LOCK_TRIGGER_ACCESS, transOwner); closeConnection(conn); } } /** * <p> * Store the given <code>{@link org.quartz.JobDetail}</code>. * </p> * * @param newJob * The <code>JobDetail</code> to be stored. * @param replaceExisting * If <code>true</code>, any <code>Job</code> existing in the * <code>JobStore</code> with the same name & group should be * over-written. * @throws ObjectAlreadyExistsException * if a <code>Job</code> with the same name/group already * exists, and replaceExisting is set to false. */ public void storeJob(SchedulingContext ctxt, JobDetail newJob, boolean replaceExisting) throws ObjectAlreadyExistsException, JobPersistenceException { Connection conn = getConnection(); boolean transOwner = false; try { if(isLockOnInsert() || replaceExisting) { getLockHandler().obtainLock(conn, LOCK_TRIGGER_ACCESS); transOwner = true; //getLockHandler().obtainLock(conn, LOCK_JOB_ACCESS); } storeJob(conn, ctxt, newJob, replaceExisting); commitConnection(conn); } catch (JobPersistenceException e) { rollbackConnection(conn); throw e; } finally { releaseLock(conn, LOCK_TRIGGER_ACCESS, transOwner); closeConnection(conn); } } /** * <p> * Remove (delete) the <code>{@link org.quartz.Job}</code> with the given * name, and any <code>{@link org.quartz.Trigger}</code> s that reference * it. * </p> * * <p> * If removal of the <code>Job</code> results in an empty group, the * group should be removed from the <code>JobStore</code>'s list of * known group names. * </p> * * @param jobName * The name of the <code>Job</code> to be removed. * @param groupName * The group name of the <code>Job</code> to be removed. * @return <code>true</code> if a <code>Job</code> with the given name & * group was found and removed from the store. */ public boolean removeJob(SchedulingContext ctxt, String jobName, String groupName) throws JobPersistenceException { Connection conn = getConnection(); boolean transOwner = false; try { getLockHandler().obtainLock(conn, LOCK_TRIGGER_ACCESS); transOwner = true; //getLockHandler().obtainLock(conn, LOCK_JOB_ACCESS); boolean removed = removeJob(conn, ctxt, jobName, groupName, true); commitConnection(conn); return removed; } catch (JobPersistenceException e) { rollbackConnection(conn); throw e; } finally { releaseLock(conn, LOCK_TRIGGER_ACCESS, transOwner); closeConnection(conn); } } /** * <p> * Retrieve the <code>{@link org.quartz.JobDetail}</code> for the given * <code>{@link org.quartz.Job}</code>. * </p> * * @param jobName * The name of the <code>Job</code> to be retrieved. * @param groupName * The group name of the <code>Job</code> to be retrieved. * @return The desired <code>Job</code>, or null if there is no match. */ public JobDetail retrieveJob(SchedulingContext ctxt, String jobName, String groupName) throws JobPersistenceException { Connection conn = getConnection(); try { // no locks necessary for read... JobDetail job = retrieveJob(conn, ctxt, jobName, groupName); commitConnection(conn); return job; } catch (JobPersistenceException e) { rollbackConnection(conn); throw e; } finally { closeConnection(conn); } } /** * <p> * Store the given <code>{@link org.quartz.Trigger}</code>. * </p> * * @param newTrigger * The <code>Trigger</code> to be stored. * @param replaceExisting * If <code>true</code>, any <code>Trigger</code> existing in * the <code>JobStore</code> with the same name & group should * be over-written. * @throws ObjectAlreadyExistsException * if a <code>Trigger</code> with the same name/group already * exists, and replaceExisting is set to false. */ public void storeTrigger(SchedulingContext ctxt, Trigger newTrigger, boolean replaceExisting) throws ObjectAlreadyExistsException, JobPersistenceException { Connection conn = getConnection(); boolean transOwner = false; try { if(isLockOnInsert() || replaceExisting) { getLockHandler().obtainLock(conn, LOCK_TRIGGER_ACCESS); transOwner = true; //getLockHandler().obtainLock(conn, LOCK_JOB_ACCESS); } storeTrigger(conn, ctxt, newTrigger, null, replaceExisting, STATE_WAITING, false, false); commitConnection(conn); } catch (JobPersistenceException e) { rollbackConnection(conn); throw e; } finally { releaseLock(conn, LOCK_TRIGGER_ACCESS, transOwner); closeConnection(conn); } } /** * <p> * Remove (delete) the <code>{@link org.quartz.Trigger}</code> with the * given name. * </p> * * <p> * If removal of the <code>Trigger</code> results in an empty group, the * group should be removed from the <code>JobStore</code>'s list of * known group names. * </p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -