# jedis 与 redission 实现分布式锁 (干货带源码)
JVM中提供了处理锁机制api(synchronize/Lock)等,这种是jvm层面的。到了分布式就没作用了。所以需要分布式锁
# 分布式锁要满足哪些要求呢?
排他性:在同一时间只会有一个客户端能获取到锁,其它客户端无法同时获取
避免死锁: 这把锁在一段有限的时间之后,一定会被释放(正常释放或异常释放)
高可用:获取或释放锁的机制必须高可用且性能佳
# 目前主流的分布式锁实现方式
基于数据库的实现方式
基于redis的实现方式(推荐)
基于Zookeeper的实现方式
# 基于Jedis的Redis分布式锁的实现
- RedisLock Util
@Service
public class RedisLock {
Logger logger = LoggerFactory.getLogger(this.getClass());
private String lock_key = "redis_lock"; //锁键
protected long internalLockLeaseTime = 3000;//锁过期时间
private long timeout = 999999; //获取锁的超时时间
//SET命令的参数
SetParams params = SetParams.setParams().nx().px(internalLockLeaseTime);
@Autowired
RedisCacheConfiguration redisCacheConfiguration;
/**
* 加锁
* @param id
* @return
*/
public boolean lock(String id){
Jedis jedis = redisCacheConfiguration.redisPoolFactory().getResource();
try{
String lock = jedis.set(lock_key, id, params);
if("OK".equals(lock)){
return true;
}
return false;
}finally {
jedis.close();
}
}
/**
* 解锁
* @param id
* @return
*/
public boolean unlock(String id){
Jedis jedis = redisCacheConfiguration.redisPoolFactory().getResource();
String script =
"if redis.call('get',KEYS[1]) == ARGV[1] then" +
" return redis.call('del',KEYS[1]) " +
"else" +
" return 0 " +
"end";
try {
Object result = jedis.eval(script, Collections.singletonList(lock_key),
Collections.singletonList(id));
if("1".equals(result.toString())){
return true;
}
return false;
}finally {
jedis.close();
}
}
}
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
使用
boolean lock = redisLock.lock(likeLock);
if (Objects.equals(false, lock)) {
throw new BusinessException("等待操作,请勿多次频繁操作");
}
try {
//业务代码
} finally {
redisLock.unlock(likeLock);
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 基于Redission的Redis分布式锁的实现
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
String key = SystemConstants.LOYALTY_MEMBER_POINT_LOCK_PRE + cusId;
RLock lock = redissonClient.getLock(key);
try {
lock.lock();
// 排他性檢查
// 业务
}
finally {
lock.unlock();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 相关资料
Java分布式锁,搞懂分布式锁实现看这篇文章就对了 (opens new window)
基于Jedis的Redis分布式锁实现 (opens new window)
全量分析 阅读量: