redisson分布式锁lua脚本
时间: 2023-09-28 08:08:04 浏览: 126
使用Redisson分布式锁的Lua脚本可以通过在resources文件夹下的luascript文件夹中创建lock.lua和unlock.lua来实现。 Redisson本身是基于Lua脚本来保证原子性的,但是使用Redisson需要额外引用依赖并进行配置,增加了学习成本。如果需求不是很复杂,完全可以使用简单的Lua脚本来实现分布式锁。<span class="em">1</span><span class="em">2</span><span class="em">3</span>
#### 引用[.reference_title]
- *1* *2* *3* [(redis + lua脚本 )实现redis分布式锁](https://blog.csdn.net/qq_38345773/article/details/114991929)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"]
[ .reference_list ]
相关问题
Redisson分布式锁原理
Redisson分布式锁是基于Redis实现的一种分布式锁,其原理如下:
1. 获取锁时,使用Redis的setnx命令设置一个指定名称的键值对,如果该键不存在,则设置成功,返回1;如果该键已存在,则设置失败,返回0。
2. 获取锁后,设置一个过期时间,防止锁一直被持有导致死锁。
3. 释放锁时,使用Redis的del命令删除该键值对,释放锁资源。
4. 为了避免误删其他线程的锁,Redisson使用了Lua脚本来确保删除锁的原子性。
5. Redisson还提供了可重入锁、公平锁、红锁等多种锁实现方式,可以根据实际需求进行选择。
总的来说,Redisson分布式锁的实现原理就是利用Redis的原子性操作来实现分布式锁,通过设置过期时间和使用Lua脚本保证锁的正确释放和防止误删其他线程的锁。
redisson 分布式锁源码分析
Redisson是一个基于Redis的Java驻留库,提供了分布式和线程安全的Java数据结构。Redisson的分布式锁实现是基于Redis的setnx命令和Lua脚本实现的。下面是Redisson分布式锁的源码分析:
1.获取锁
Redisson的分布式锁获取方法是tryAcquire方法,该方法首先会尝试使用setnx命令在Redis中创建一个key,如果创建成功则表示获取锁成功,否则会进入自旋等待。在自旋等待期间,Redisson会使用watchDog机制来监控锁的状态,如果锁被其他线程释放,则会重新尝试获取锁。
2.释放锁
Redisson的分布式锁释放方法是release方法,该方法会使用Lua脚本来判断当前线程是否持有锁,如果持有锁则会使用del命令删除锁的key。
3.watchDog机制
Redisson的watchDog机制是用来监控锁的状态的,该机制会在获取锁时启动一个定时任务,定时任务会检查锁的状态,如果锁被其他线程释放,则会重新尝试获取锁。
```java
// 获取锁
public boolean tryAcquire(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
long time = unit.toMillis(waitTime);
long current = System.currentTimeMillis();
final long threadId = Thread.currentThread().getId();
final long leaseTimeInMillis = unit.toMillis(leaseTime);
while (true) {
if (tryAcquire()) {
scheduleExpirationRenewal(threadId, leaseTimeInMillis);
return true;
}
time -= (System.currentTimeMillis() - current);
if (time <= 0) {
return false;
}
current = System.currentTimeMillis();
if (Thread.interrupted()) {
throw new InterruptedException();
}
// watchDog机制
RFuture<RedissonLockEntry> future = subscribe(threadId);
if (!future.await(time, TimeUnit.MILLISECONDS)) {
return false;
}
}
}
// 释放锁
public void unlock() {
if (isHeldByCurrentThread()) {
unlockInner();
}
}
private void unlockInner() {
Long ttl = commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_LONG,
"if (redis.call('hexists', KEYS[1], ARGV[2]) == 0) then return nil end; " +
"local counter = redis.call('hincrby', KEYS[1], ARGV[2], -1); " +
"if (counter > 0) then return 0 end; " +
"redis.call('del', KEYS[1]); " +
"redis.call('publish', KEYS[2], ARGV[1]); " +
"return 1;",
Arrays.<Object>asList(getName(), getChannelName()),
encode(new UnlockMessage(getName(), getLockName())),
id);
cancelExpirationRenewal();
if (ttl == null) {
throw new IllegalMonitorStateException("attempt to unlock lock, not locked by current thread by node id: " + id + " thread-id: " + Thread.currentThread().getId());
}
if (ttl == -1) {
get(lockName).deleteAsync();
}
}
```
阅读全文