📄 jobstoresupport.java
字号:
public boolean getUseDBLocks() {
return useDBLocks;
}
public boolean isLockOnInsert() {
return lockOnInsert;
}
/**
* Whether or not to obtain locks when inserting new jobs/triggers.
* Defaults to <code>true</code>, which is safest - some db's (such as
* MS SQLServer) seem to require this to avoid deadlocks under high load,
* while others seem to do fine without.
*
* <p>Setting this property to <code>false</code> will provide a
* significant performance increase during the addition of new jobs
* and triggers.</p>
*
* @param lockOnInsert
*/
public void setLockOnInsert(boolean lockOnInsert) {
this.lockOnInsert = lockOnInsert;
}
public long getMisfireThreshold() {
return misfireThreshold;
}
/**
* The the number of milliseconds by which a trigger must have missed its
* next-fire-time, in order for it to be considered "misfired" and thus
* have its misfire instruction applied.
*
* @param misfireThreshold
*/
public void setMisfireThreshold(long misfireThreshold) {
if (misfireThreshold < 1) {
throw new IllegalArgumentException(
"Misfirethreshold must be larger than 0");
}
this.misfireThreshold = misfireThreshold;
}
public boolean isDontSetAutoCommitFalse() {
return dontSetAutoCommitFalse;
}
/**
* Don't call set autocommit(false) on connections obtained from the
* DataSource. This can be helpfull in a few situations, such as if you
* have a driver that complains if it is called when it is already off.
*
* @param b
*/
public void setDontSetAutoCommitFalse(boolean b) {
dontSetAutoCommitFalse = b;
}
public boolean isTxIsolationLevelSerializable() {
return setTxIsolationLevelSequential;
}
/**
* Set the transaction isolation level of DB connections to sequential.
*
* @param b
*/
public void setTxIsolationLevelSerializable(boolean b) {
setTxIsolationLevelSequential = b;
}
/**
* Whether or not the query and update to acquire a Trigger for firing
* should be performed after obtaining an explicit DB lock (to avoid
* possible race conditions on the trigger's db row). This is the
* behavior prior to Quartz 1.6.3, but is considered unnecessary for most
* databases (due to the nature of the SQL update that is performed),
* and therefore a superfluous performance hit.
*/
public boolean isAcquireTriggersWithinLock() {
return acquireTriggersWithinLock;
}
/**
* Whether or not the query and update to acquire a Trigger for firing
* should be performed after obtaining an explicit DB lock. This is the
* behavior prior to Quartz 1.6.3, but is considered unnecessary for most
* databases, and therefore a superfluous performance hit.
*/
public void setAcquireTriggersWithinLock(boolean acquireTriggersWithinLock) {
this.acquireTriggersWithinLock = acquireTriggersWithinLock;
}
/**
* <p>
* Set the JDBC driver delegate class.
* </p>
*
* @param delegateClassName
* the delegate class name
*/
public void setDriverDelegateClass(String delegateClassName)
throws InvalidConfigurationException {
this.delegateClassName = delegateClassName;
}
/**
* <p>
* Get the JDBC driver delegate class name.
* </p>
*
* @return the delegate class name
*/
public String getDriverDelegateClass() {
return delegateClassName;
}
public String getSelectWithLockSQL() {
return selectWithLockSQL;
}
/**
* <p>
* set the SQL statement to use to select and lock a row in the "locks"
* table.
* </p>
*
* @see StdRowLockSemaphore
*/
public void setSelectWithLockSQL(String string) {
selectWithLockSQL = string;
}
protected ClassLoadHelper getClassLoadHelper() {
return classLoadHelper;
}
/**
* Get whether the threads spawned by this JobStore should be
* marked as daemon. Possible threads include the <code>MisfireHandler</code>
* and the <code>ClusterManager</code>.
*
* @see Thread#setDaemon(boolean)
*/
public boolean getMakeThreadsDaemons() {
return makeThreadsDaemons;
}
/**
* Set whether the threads spawned by this JobStore should be
* marked as daemon. Possible threads include the <code>MisfireHandler</code>
* and the <code>ClusterManager</code>.
*
* @see Thread#setDaemon(boolean)
*/
public void setMakeThreadsDaemons(boolean makeThreadsDaemons) {
this.makeThreadsDaemons = makeThreadsDaemons;
}
/**
* Get whether to set the class load context of spawned threads to that
* of the initializing thread.
*/
public boolean isThreadsInheritInitializersClassLoadContext() {
return threadsInheritInitializersClassLoadContext;
}
/**
* Set whether to set the class load context of spawned threads to that
* of the initializing thread.
*/
public void setThreadsInheritInitializersClassLoadContext(
boolean threadsInheritInitializersClassLoadContext) {
this.threadsInheritInitializersClassLoadContext = threadsInheritInitializersClassLoadContext;
}
/**
* Get whether to check to see if there are Triggers that have misfired
* before actually acquiring the lock to recover them. This should be
* set to false if the majority of the time, there are are misfired
* Triggers.
*/
public boolean getDoubleCheckLockMisfireHandler() {
return doubleCheckLockMisfireHandler;
}
/**
* Set whether to check to see if there are Triggers that have misfired
* before actually acquiring the lock to recover them. This should be
* set to false if the majority of the time, there are are misfired
* Triggers.
*/
public void setDoubleCheckLockMisfireHandler(
boolean doubleCheckLockMisfireHandler) {
this.doubleCheckLockMisfireHandler = doubleCheckLockMisfireHandler;
}
//---------------------------------------------------------------------------
// interface methods
//---------------------------------------------------------------------------
protected Log getLog() {
return log;
}
/**
* <p>
* Called by the QuartzScheduler before the <code>JobStore</code> is
* used, in order to give it a chance to initialize.
* </p>
*/
public void initialize(ClassLoadHelper loadHelper,
SchedulerSignaler signaler) throws SchedulerConfigException {
if (dsName == null) {
throw new SchedulerConfigException("DataSource name not set.");
}
classLoadHelper = loadHelper;
if(isThreadsInheritInitializersClassLoadContext()) {
log.info("JDBCJobStore threads will inherit ContextClassLoader of thread: " + Thread.currentThread().getName());
initializersLoader = Thread.currentThread().getContextClassLoader();
}
this.signaler = signaler;
// If the user hasn't specified an explicit lock handler, then
// choose one based on CMT/Clustered/UseDBLocks.
if (getLockHandler() == null) {
// If the user hasn't specified an explicit lock handler,
// then we *must* use DB locks with clustering
if (isClustered()) {
setUseDBLocks(true);
}
if (getUseDBLocks()) {
getLog().info(
"Using db table-based data access locking (synchronization).");
setLockHandler(
new StdRowLockSemaphore(getTablePrefix(), getSelectWithLockSQL()));
} else {
getLog().info(
"Using thread monitor-based data access locking (synchronization).");
setLockHandler(new SimpleSemaphore());
}
}
if (!isClustered()) {
try {
cleanVolatileTriggerAndJobs();
} catch (SchedulerException se) {
throw new SchedulerConfigException(
"Failure occured during job recovery.", se);
}
}
}
/**
* @see org.quartz.spi.JobStore#schedulerStarted()
*/
public void schedulerStarted() throws SchedulerException {
if (isClustered()) {
clusterManagementThread = new ClusterManager();
if(initializersLoader != null)
clusterManagementThread.setContextClassLoader(initializersLoader);
clusterManagementThread.initialize();
} else {
try {
recoverJobs();
} catch (SchedulerException se) {
throw new SchedulerConfigException(
"Failure occured during job recovery.", se);
}
}
misfireHandler = new MisfireHandler();
if(initializersLoader != null)
misfireHandler.setContextClassLoader(initializersLoader);
misfireHandler.initialize();
}
/**
* <p>
* Called by the QuartzScheduler to inform the <code>JobStore</code> that
* it should free up all of it's resources because the scheduler is
* shutting down.
* </p>
*/
public void shutdown() {
if (clusterManagementThread != null) {
clusterManagementThread.shutdown();
}
if (misfireHandler != null) {
misfireHandler.shutdown();
}
try {
DBConnectionManager.getInstance().shutdown(getDataSource());
} catch (SQLException sqle) {
getLog().warn("Database connection shutdown unsuccessful.", sqle);
}
}
public boolean supportsPersistence() {
return true;
}
//---------------------------------------------------------------------------
// helper methods for subclasses
//---------------------------------------------------------------------------
protected abstract Connection getNonManagedTXConnection()
throws JobPersistenceException;
/**
* Wrap the given <code>Connection</code> in a Proxy such that attributes
* that might be set will be restored before the connection is closed
* (and potentially restored to a pool).
*/
protected Connection getAttributeRestoringConnection(Connection conn) {
return (Connection)Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class[] { Connection.class },
new AttributeRestoringConnectionInvocationHandler(conn));
}
protected Connection getConnection() throws JobPersistenceException {
Connection conn = null;
try {
conn = DBConnectionManager.getInstance().getConnection(
getDataSource());
} catch (SQLException sqle) {
throw new JobPersistenceException(
"Failed to obtain DB connection from data source '"
+ getDataSource() + "': " + sqle.toString(), sqle);
} catch (Throwable e) {
throw new JobPersistenceException(
"Failed to obtain DB connection from data source '"
+ getDataSource() + "': " + e.toString(), e,
JobPersistenceException.ERR_PERSISTENCE_CRITICAL_FAILURE);
}
if (conn == null) {
throw new JobPersistenceException(
"Could not get connection from DataSource '"
+ getDataSource() + "'");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -