原理
quartz用的是行锁,for update 是排他锁,一旦获取TRIGGER_ACCESS行锁,这时候针对这行读写都不能进行
session 1
set autocommit=0;
select * from QRTZ_LOCKS where lock_name = 'TRIGGER_ACCESS' for update ;
session2
session2将会被锁住
select * from QRTZ_LOCKS where lock_name = 'TRIGGER_ACCESS' for update ;
//等待
代码实现
自定义SemaPhore
public interface Semaphore {
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Interface.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/**
* Grants a lock on the identified resource to the calling thread (blocking
* until it is available).
*
* @param conn Database connection used to establish lock. Can be null if
* <code>{@link #requiresConnection()}</code> returns false.
*
* @return true if the lock was obtained.
*/
boolean obtainLock(Connection conn, String lockName) throws LockException;
/**
* Release the lock on the identified resource if it is held by the calling
* thread.
*/
void releaseLock(String lockName) throws LockException;
/**
* Whether this Semaphore implementation requires a database connection for
* its lock management operations.
*
* @see #obtainLock(Connection, String)
* @see #releaseLock(String)
*/
boolean requiresConnection();
}
实现者有DBSemaphore,SimpleSemaphore,JTANonClusteredSemaphore
obtainLock,是获取锁
对于DBSemaphore是获取数据库表的行的排它锁.
public synchronized boolean obtainLock(Connection conn, String lockName) {
lockName = lockName.intern();
if(log.isDebugEnabled()) {
log.debug(
"Lock '" + lockName + "' is desired by: "
+ Thread.currentThread().getName());
}
if (!isLockOwner(lockName)) {
if(log.isDebugEnabled()) {
log.debug(
"Lock '" + lockName + "' is being obtained: "
+ Thread.currentThread().getName());
}
while (locks.contains(lockName)) {
try {
this.wait();
} catch (InterruptedException ie) {
if(log.isDebugEnabled()) {
log.debug(
"Lock '" + lockName + "' was not obtained by: "
+ Thread.currentThread().getName());
}
}
}
if(log.isDebugEnabled()) {
log.debug(
"Lock '" + lockName + "' given to: "
+ Thread.currentThread().getName());
}
getThreadLocks().add(lockName);
locks.add(lockName);
} else if(log.isDebugEnabled()) {
log.debug(
"Lock '" + lockName + "' already owned by: "
+ Thread.currentThread().getName()
+ " -- but not owner!",
new Exception("stack-trace of wrongful returner"));
}
return true;
}