pom.xml
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.15.1</version>
</dependency>
application.yml
spring:
redis:
host: localhost
port: 6379
模拟获取锁
注意下面只是示例,生产环境不要这样用
package com.example.demo.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
@Slf4j
@RestController
@RequiredArgsConstructor
public class RedissonController {
private final RedissonClient redissonClient;
/**
* 第一次调用lock方法,会立即获取锁并持有锁30秒,30秒后释放锁,立即返回我获取到了锁
* 第二次调用lock方法,立即返回我没有获取到锁
*/
@GetMapping("lock")
public String lock() throws InterruptedException {
RLock lock = redissonClient.getLock("lock");
//不等待,立即获取锁。并设置持有锁的时间为30秒,到期时自动释放锁(注意:如果此时业务未执行完,也会释放锁!)
boolean tryLock = lock.tryLock(0L,30, TimeUnit.SECONDS);
if (tryLock) {
return "我获取到了锁";
}
return "我没有获取到锁";
}
}
生产环境使用
@GetMapping("lock")
public String lock() throws InterruptedException {
RLock lock = redissonClient.getLock("lock");
//不等待,立即获取锁。并设置持有锁的时间为300秒,到期时自动释放锁(注意:如果此时业务未执行完,也会释放锁!根据实际来设置最长不建议超过5分钟!)
boolean tryLock = lock.tryLock(0L, 300, TimeUnit.SECONDS);
if (tryLock) {
try {
//耗时业务,不需要加锁的业务尽量不要放进来。要保证锁的粒度尽可能的小。
return "我获取到了锁";
} catch (Exception e) {
log.error("执行业务异常",e);
throw new RuntimeException(e.getMessage());
} finally {
//手动解锁,不要等锁过期自动释放,因为不释放,业务执行完还是会持有锁,所以业务执行完一定要在 finally 手动解锁
lock.unlock();
}
}
return "我没有获取到锁";
}