转载(http://ju.outofmemory.cn/entry/338909)基于 redis 的 spring boot 分布式锁实现

随着现在 分布式 架构越来越盛行,在很多场景下需要使用到 分布式锁 。分布式 锁 的实现有很多种,比如基于 数据库 、 zookeeper 
等,本文主要介绍使用 Redis 
做分布式锁的方式,并封装成 spring boot s tar ter,方便使用

一. Redis 
分布式锁的实现以及存在的问题

锁是针对某个资源,保证其访问的互斥性,在实际使用当中,这个资源一般是一个字符串。使用 Redis 
实现锁,主要是将资源放到 Redis 
当中,利用其原子性,当其他 线程 访问时,如果 Redis 
中已经存在这个资源,就不允许之后的一些操作。spring boot使用 Redis 
的操作主要是通过 RedisTemplate 
来实现,一般步骤如下:

  1. 将锁资源放入 Redis 
    (注意是当 key 不存在时才能放成功,所以使用 setIfAbsent 
    方法):
redisTemplate.opsForValue().setIfAbsent("key", "value");
  1. 设置过期 时间
redisTemplate.expire("key", 30000, TimeUnit.MILLISECONDS);
  1. 释放锁
redisTemplate.delete("key");

一般情况下,这样的实现就能够满足锁的 需求 了,但是如果在调用 setIfAbsent 
方法之后线程挂掉了,即没有给锁定的资源设置过期时间,默认是永不过期,那么这个锁就会一直存在。所以需要保证设置锁及其过期时间两个操作的原子性,spring data的 RedisTemplate 
当中并没有这样的方法。但是在jedis当中是有这种原子操作的方法的,需要通过 RedisTemplate 
的 execute 
方法获取到jedis里操作命令的对象, 代码 如下:

String result = redisTemplate.execute(new RedisCallback<String>() {
	@Override
	public String doInRedis(RedisConnection connection) throws DataAccessException {
		JedisCommands commands = (JedisCommands) connection.getNativeConnection();
		return commands.set(key, "锁定的资源", "NX", "PX", expire);
	}
});

注意: 
Redis 
从2.6.12版本开始 set 
命令支持 NX 
、 PX 
这些 参数 来达到 setnx 
、 setex 
、 psetex 
命令的效果,文档参见:

http ://doc.redisfans.com/string/set.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值