loading...
Redis开启分布式锁
Published in:2022-01-31 | category: Redis
Words: 458 | Reading time: 2min | reading:

使用的API方法

RedisConnection

获取连接池对象

1
RedisTemplate.getConnectionFactory().getConnection();

setNX(byte[] key , byte[] value)

将给定的keys赋值到他们相应的values上。只要有一个key已经存在,SetNX返回0,即false;只要不存在,SetNX返回true。

expire(byte[] key , long seconds)

redis可以通过expire命令来设置key的过期时间。

  1. 在小于2.1.3的redis版本里,只能对key设置一次expire。redis2.1.3和之后的版本里,可以多次对key使用expire命令,更新key的expire time。
  1. redis术语里面,把设置了expire time的key 叫做:volatile keys。 意思就是不稳定的key。

  2. 如果对key使用set或del命令,那么也会移除expire time。尤其是set命令,这个在编写程序的时候需要注意一下。

ttl(byte[] key)

以秒为单位,返回给定key的生存时间

返回值:

1
2
3
当 key 不存在时,返回 -2 。
当 key 存在但没有设置剩余生存时间时,返回 -1 。
否则,以秒为单位,返回 key 的剩余生存时间。

在 Redis 2.8 以前,当 key 不存在,或者 key 没有设置剩余生存时间时,命令都返回 -1 。

创建分布式锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
*
* @param lockName 竞争获取锁定名称
* @param acquireTime 获取等待时间, 毫秒
* @param releaseTime 锁超时自动失效时间, 毫秒
* @return
*/
public String tryLock(String lockName, long acquireTime, long releaseTime) {

String identif = UUID.randomUUID().toString();
String lockKey = "lock:" + lockName;
long endTime = System.currentTimeMillis() + acquireTime;
int times = 0;

RedisConnection conn = null;
try {
conn = bssRedisClient.getRedisTemplate().getConnectionFactory().getConnection();
while (System.currentTimeMillis() < endTime) {
if (conn.setNX(lockKey.getBytes(), identif.getBytes())) {
conn.expire(lockKey.getBytes(), releaseTime / 1000);
return identif;
}
times += 1;

if (conn.ttl(lockKey.getBytes()) == -1) {
conn.expire(lockKey.getBytes(), releaseTime / 1000);
}

try {
//设置线程睡眠时间 10000h
TimeUnit.MILLISECONDS.sleep(1000 * 10);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
} finally {
if (null != conn) {
conn.close();
}
}

logger.error("Number of '{}' failed retry attempts: {}", lockName, times);
return null;
}
Prev:
Redis缓存雪崩
Next:
Redis删除策略
catalog
catalog