I've two java applications (app1, app2). Both applications are using JedisCluster
client for Redis cluster. app1 write or read data from Redis cluster. app2 is like a scheduler which only writes some data to Redis cluster. it runs after a fixed time of interval. I've to ensure that when app2 is doing write operation, no data is served or written for app1 until the whole write operation is finished by app2. I want to lock Redis cluster for app1 when app2 is running. it doesn't matter whether app1 get an exception or not at that time.

- 15,409
- 15
- 81
- 150

- 541
- 5
- 13
-
might be useful to look into a distributed redis lock – Debosmit Ray Apr 25 '17 at 05:04
3 Answers
It seems you need application-level lock to ensure thread-safe operations from different application scopes which is pretty much same as distributed lock. For Jedis, a quick search yields Jedis-lock library.
Jedis jedis = new Jedis("localhost");
JedisLock lock = new JedisLock(jedis, "lockname", 10000, 30000);
lock.acquire();
try {
// do some stuff
}
finally {
lock.release();
}
System.out.println(jedis.isLocked());
System.out.println(jedis.isRemoteLocked());
Edit
According to Jedis-lock's owner (Thanks for this project), the project is no longer maintained/pull requests are not merged anymore. This fork is now actively maintained and has new features:
- New
SET
API in place of oldSETNX
- Lock ownership safety using atomic LUA scripting on
release()
- Locking support for
JedisCluster

- 15,409
- 15
- 81
- 150
-
What if the application crashes before executing finally block, it may leave the Redis locked forever, better to aquire lock using some time out. – AmanSinghal Apr 25 '17 at 05:27
-
1@AmanSinghal yes, you're right but the API used here `JedisLock(Jedis jedis, String lockKey, int acquireTimeoutMillis, int expiryTimeMillis)` which I set 30000 here. So it will timeout eventually if any malfunctions occur. – Kaidul Apr 25 '17 at 05:40
-
Yup, I noticed that just want to highlight it so as to make people aware of this problem. – AmanSinghal Apr 25 '17 at 07:16
Have you tried Redisson's lock? It's a Redis based framework.
It offers Lock object implemented java.util.concurrent.locks.Lock
interface and easy to use.
RedissonClient redisson = Redisson.create(config);
RLock lock = redisson.getLock("myLock");
lock.lock();
try {
// ...
} finally {
lock.unlock();
}
It also offers Asynchronous version of lock object.

- 10,283
- 1
- 62
- 71
I've achieved mutual exclusion on a race condition on Jedis, using Distributed locks with Redis because "GETs" are no threadsafe there is a need to implement mutex on a multithreaded environment. this was implemented with a JedisSentinelPool on getJedis()
public void methodWithRaceCondition() {
Jedis jedis = getJedis();
try {
lock();
//code that requires multiple exclusion on data read
jedis.//get hget ....
} catch (Exception up) {
logException(up);
} finally {
//ALWAYS RELEASE LOCK
releaseLock(jedis);
closeJedis(jedis);
jedis = null;
}
}
private void releaseLock(Jedis jedis) {
String semaphore = "SEMAPHORE";
try {
if (!jedis.get(semaphore).isEmpty()) {
jedis.del(semaphore);
}
} catch (final RuntimeException e) {
LOGGER_SUB.error(e);
}
}
private void lock(Jedis jedis) throws InterruptedException {
synchronized (this) {
try {
String lock = openSemaphore(jedis);
while (lock == null || "OK".compareTo(lock) != 0) {
this.wait(1);
LOGGER_SUB.info("WAITED");
lock = openSemaphore(jedis);
}
} catch (final RuntimeException e) {
LOGGER_SUB.error(e);
}
}
}
/**
* Distributed locks with Redis
* https://redis.io/topics/distlock
* Set value =1
* NX if not exixts
* PX for millisec
*
* @param jedis
* @return
*/
private String openSemaphore(Jedis jedis) {
return jedis.set("SEMAPHORE", "1", "NX", "PX", 30000);
}

- 146
- 8