Created
April 30, 2018 21:18
-
-
Save trasa/8cd776d2e0c068fe5ceeaa244b1184c8 to your computer and use it in GitHub Desktop.
Simple Redis Lock
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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