Redis分布式锁简单案例 向右看齐 2021-12-17 12:19 190阅读 0赞 实际开发中,当系统是分布式集群情况下,多个请求对一条数据进行更新时,为了数据安全,我们必须要将这条数据锁住,但是集群负载情况下使用jdk自带的锁此时已经无济于事。我们必须要使用数据库锁。下面是基于redis实现的分布式锁简单案例。 ### 1、锁接口 ### /** * 分布式锁 * @author zhanglei */ public interface YBLock { /** * 获取锁 * @return boolean */ boolean acquire(); /** * 释放锁 */ void release(); } ### 2、回调接口 ### /** * 获取锁失败,回调接口 * * @author zhanglei */ public interface LockBack { void fallback(RedisLock redisLock); } ### 3、redis锁实现 ### /** * redis分布式锁实现 * * 锁本身并不是线程安全的,使用请在函数内部创建新的锁实例使用。 * * @author zhanglei */ @SuppressWarnings("unchecked") public class RedisLock implements YBLock{ private static Logger logger = LoggerFactory.getLogger(RedisLock.class); /** * redisTemplate */ private RedisTemplate redisTemplate; /** * 获取锁失败,回调 */ private LockBack lockBack; /** * 锁字符串 */ private String lockKey; /** * 锁过期时间 默认10秒 放置程序故障导致的锁永久不释放 单位毫秒 */ private int expireTime = 1000 * 10; public RedisLock(String lockKey){ this.lockKey = lockKey; synchronized (RedisLock.class){ if(redisTemplate == null){ redisTemplate = SpringContext.getBean(StringRedisTemplate.class); } } } public RedisLock(String lockKey,int expireTime){ this(lockKey); this.expireTime = expireTime; } public RedisLock(String lockKey,int expireTime,LockBack lockBack){ this(lockKey,expireTime); this.lockBack = lockBack; } public RedisLock(String lockKey, LockBack lockBack){ this(lockKey); this.lockBack = lockBack; } /** * 获取锁 */ @Override public boolean acquire() { //过期时间值 String expire = Long.toString(System.currentTimeMillis() + this.expireTime); try { while (true) { //在redis中设置值 boolean acq = redisTemplate.opsForValue().setIfAbsent(this.lockKey, expire); //设置成功 if (acq) { logger.info("get redis lock success!"); //设置过期时间 redisTemplate.expire(this.lockKey, expireTime, TimeUnit.MILLISECONDS); return true; } //如果获取锁失败,调用回调 if (this.lockBack != null) { this.lockBack.fallback(this); return false; } //睡眠100毫秒 Thread.sleep(100); } }catch (Exception e){ logger.error(e.getMessage(),e); } return false; } /** * 释放锁 */ @Override public void release() { this.redisTemplate.delete(this.lockKey); } public String getLockKey() { return lockKey; } public void setLockKey(String lockKey) { this.lockKey = lockKey; } public int getExpireTime() { return expireTime; } public void setExpireTime(int expireTime) { this.expireTime = expireTime; } } ### 4、获取锁工具类 ### /** * 获取锁 */ public final class LockUtil { private static final String LOCK_KEY_NULL = "lock key not null"; private LockUtil(){} public static RedisLock getLock(String lockKey){ Assert.notEmpty(LOCK_KEY_NULL,lockKey); return new RedisLock(lockKey); } public static RedisLock getLock(String lockKey,LockBack lockBack){ Assert.notEmpty(LOCK_KEY_NULL,lockKey); return new RedisLock(lockKey,lockBack); } public static RedisLock getLock(String lockKey,int expire){ Assert.notEmpty(LOCK_KEY_NULL,lockKey); return new RedisLock(lockKey,expire); } public static RedisLock getLock(String lockKey,int expire,LockBack lockBack){ Assert.notEmpty(LOCK_KEY_NULL,lockKey); return new RedisLock(lockKey,expire,lockBack); } } 以上代码可以实现简单的分布式锁
还没有评论,来说两句吧...