/*******************************************************************************
* Copyright 2014 Miami-Dade County
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package org.sharegov.cirm.rdb;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.sharegov.cirm.CirmTransaction;
/**
* Locking strategy for CirmTransactions that locks, iff both maxExecutionCount is exceeded and noLockTime is exceeded.
*
* E.g. Set noLockTime to x secs to never lock if a Transaction has not been executed that long, independent of retries.
* E.g. if noLockTime is exceeded and there have been more than maxExecutionCount attempts (retries + first), suggest to lock.
*
* @author Thomas Hilpold
*
*/
public class SimpleDBLockStrategy implements DBLockStrategy
{
private volatile int maxExecutionCount = 1;
private volatile double noLockTimeSec = 5;
private final ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock(true);
private final ReadLock r = rwlock.readLock();
private final WriteLock w = rwlock.writeLock();
/**
* Returns true, iff both maxExecutionCount is exceeded and noLockTime is exceeded.
* @param t
* @return
*/
public boolean isLockRequired(CirmTransaction<?> t)
{
r.lock();
try {
int executions = t.getExecutionCount();
double secsSinceFirstExecution = t.getTotalExecutionTimeSecs();
return (executions > maxExecutionCount && secsSinceFirstExecution > noLockTimeSec);
} finally
{
r.unlock();
}
}
public int getMaxExecutionCount()
{
return maxExecutionCount;
}
public void setMaxExecutionCount(int maxExecutionCount)
{
if (maxExecutionCount < 0) throw new IllegalArgumentException("maxExecutionCount must be >=0, was " + maxExecutionCount);
w.lock();
this.maxExecutionCount = maxExecutionCount;
w.unlock();
}
public double getNoLockTimeSec()
{
r.lock();
try {
return noLockTimeSec;
} finally
{
r.unlock();
}
}
public void setNoLockTimeSec(double noLockTimeSec)
{
if (noLockTimeSec < 0) throw new IllegalArgumentException("noLockTimeSec must be >=0, was " + noLockTimeSec);
w.lock();
this.noLockTimeSec = noLockTimeSec;
w.unlock();
}
}