博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
springboot2.x redis lettuce实现分布式锁
阅读量:5749 次
发布时间:2019-06-18

本文共 3886 字,大约阅读时间需要 12 分钟。

我查了很多redis分布式锁都是通过jedisclient来实现的,因为springboot2.x默认连接客户端是lettuce,所以引用一个大佬用jedis写的锁修改下。

直接贴代码

1.接口类

public interface DistributedLock {		public static final long TIMEOUT_MILLIS = 30000;		public static final int RETRY_TIMES = 10;		public static final long SLEEP_MILLIS = 500;		public boolean lock(String key);		public boolean lock(String key, int retryTimes);		public boolean lock(String key, int retryTimes, long sleepMillis);		public boolean lock(String key, long expire);		public boolean lock(String key, long expire, int retryTimes);		public boolean lock(String key, long expire, int retryTimes, long sleepMillis);		public boolean releaseLock(String key);}复制代码

2.依然是接口

public abstract class AbstractDistributedLock implements DistributedLock {	@Override	public boolean lock(String key) {		return lock(key , TIMEOUT_MILLIS, RETRY_TIMES, SLEEP_MILLIS);	}	@Override	public boolean lock(String key, int retryTimes) {		return lock(key, TIMEOUT_MILLIS, retryTimes, SLEEP_MILLIS);	}	@Override	public boolean lock(String key, int retryTimes, long sleepMillis) {		return lock(key, TIMEOUT_MILLIS, retryTimes, sleepMillis);	}	@Override	public boolean lock(String key, long expire) {		return lock(key, expire, RETRY_TIMES, SLEEP_MILLIS);	}	@Override	public boolean lock(String key, long expire, int retryTimes) {		return lock(key, expire, retryTimes, SLEEP_MILLIS);	}}复制代码

3.实现类

@Componentpublic class RedisDistributedLock extends AbstractDistributedLock {		@Autowired	@Resource(name="redisTemplateMaster")	private RedisTemplate
redisTemplate; private final Logger logger = LoggerFactory.getLogger(RedisDistributedLock.class); //private RedisTemplate
redisTemplate; private ThreadLocal
lockFlag = new ThreadLocal
(); public static final String UNLOCK_LUA; static { StringBuilder sb = new StringBuilder(); sb.append("if redis.call(\"get\",KEYS[1]) == ARGV[1] "); sb.append("then "); sb.append(" return redis.call(\"del\",KEYS[1]) "); sb.append("else "); sb.append(" return 0 "); sb.append("end "); UNLOCK_LUA = sb.toString(); } public RedisDistributedLock() { super(); }// public RedisDistributedLock(RedisTemplate
redisTemplate) {// super();// this.redisTemplate = redisTemplate;// } @Override public boolean lock(String key, long expire, int retryTimes, long sleepMillis) { boolean result = setRedis(key, expire); // 如果获取锁失败,按照传入的重试次数进行重试 while((!result) && retryTimes-- > 0){ try { logger.debug("lock failed, retrying..." + retryTimes); Thread.sleep(sleepMillis); } catch (InterruptedException e) { return false; } result = setRedis(key , expire); } return result; } private boolean setRedis(final String key, final long expire ) { try{ RedisCallback
callback = (connection) -> { String uuid = UUID.randomUUID().toString(); lockFlag.set(uuid); return connection.set(key.getBytes(Charset.forName("UTF-8")), uuid.getBytes(Charset.forName("UTF-8")), Expiration.milliseconds(expire), RedisStringCommands.SetOption.SET_IF_ABSENT); }; return (Boolean)redisTemplate.execute(callback); } catch (Exception e) { logger.error("redis lock error.", e); } return false; } @Override public boolean releaseLock(String key) { // 释放锁的时候,有可能因为持锁之后方法执行时间大于锁的有效期,此时有可能已经被另外一个线程持有锁,所以不能直接删除 try { RedisCallback
callback = (connection) -> { String value = lockFlag.get(); return connection.eval(UNLOCK_LUA.getBytes(), ReturnType.BOOLEAN ,1, key.getBytes(Charset.forName("UTF-8")), value.getBytes(Charset.forName("UTF-8"))); }; return (Boolean)redisTemplate.execute(callback); } catch (Exception e) { logger.error("release lock occured an exception", e); } finally { // 清除掉ThreadLocal中的数据,避免内存溢出 lockFlag.remove(); } return false; } }复制代码

转载于:https://juejin.im/post/5c8cb043e51d4528641bdefb

你可能感兴趣的文章
网络基础
查看>>
[MFC] 从文件读取与向文件添加数据
查看>>
ABP理论学习之领域服务
查看>>
Python之冒泡排序
查看>>
写的好帮手项目官员 - Evernote 5.4(Evernote的) 中国绿色版
查看>>
HTML最新标准HTML5小结
查看>>
RGB和YUV之比较【转】
查看>>
Windows 8 metro 真机调试程序
查看>>
PreparedStatement与Statement
查看>>
[Android Pro] DES加密 version1
查看>>
RDD.scala(源码)
查看>>
ASP.NET Razor - C# 变量
查看>>
[Step By Step]SAP HANA PAL多项式回归预测分析Polynomial Regression编程实例FORECASTWITHPOLYNOMIALR(预测)...
查看>>
JavaScript 函数replace揭秘
查看>>
Fedora9常用网络调试
查看>>
使用cgroups来控制内存使用
查看>>
kali Linux下wifi密码安全测试(1)虚拟机下usb无线网卡的挂载
查看>>
Unable to Open User Login File
查看>>
Qt 静态编译后的exe太大, 可以这样压缩.
查看>>
TortoiseGit学习系列之Windows上本地代码如何通过TortoiserGit提交到GitHub详解(图文)...
查看>>