Skip to content

Instantly share code, notes, and snippets.

@trasa
Created April 30, 2018 21:18
Show Gist options
  • Save trasa/8cd776d2e0c068fe5ceeaa244b1184c8 to your computer and use it in GitHub Desktop.
Save trasa/8cd776d2e0c068fe5ceeaa244b1184c8 to your computer and use it in GitHub Desktop.
Simple Redis Lock
import com.google.common.base.Strings;
import org.apache.commons.lang3.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisDataException;
import java.util.Random;
public class Lock {
public static final int EXPIRES_SECONDS = 30;
protected JedisPool jedisPool = null;
protected Random random = new Random();
protected String key = null;
protected String randomValue = null;
protected boolean acquired = false;
/**
* This is a simple locking mechanism that does
* not accommodate more than one Redis master.
*
* For more information, see:
* http://redis.io/topics/distlock
*/
public Lock(JedisPool jedisPool) {
this.jedisPool = jedisPool;
randomValue = Long.toString(random.nextLong());
}
public synchronized boolean tryAcquire(String name) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
// Set an expiration TTL to prevent permanent lock leakage if the owner neglects to call release().
String result = jedis.set(name, randomValue, "NX", "EX", EXPIRES_SECONDS);
if ("OK".equals(result)) {
// success!
key = name;
acquired = true;
} else {
acquired = false;
}
} catch(JedisConnectionException | JedisDataException e) {
if (jedis != null) {
jedisPool.returnBrokenResource(jedis);
jedis = null;
}
throw e;
} finally {
if (jedis != null) {
jedisPool.returnResource(jedis);
jedis = null;
}
}
return acquired;
}
public synchronized void release() {
if (!acquired) {
return;
}
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
String retrievedValue = jedis.get(key);
// if the key expired, the lock is released..
if (retrievedValue == null || retrievedValue.equals(randomValue)) {
jedis.del(key);
key = null;
acquired = false;
}
} catch(JedisConnectionException | JedisDataException e) {
if (jedis != null) {
jedisPool.returnBrokenResource(jedis);
jedis = null;
}
throw e;
} finally {
if (jedis != null) {
jedisPool.returnResource(jedis);
jedis = null;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment