分布式缓存和分布式锁
一.技术方案选型:
- lock.lock() 不设置过期时间和等待时间
- lock.lock(10,TimeUnit) 设置过期时间,超过过期时间主动释放锁
- lock.lock(20,10,TimeUnit) 设置竞争获取锁的最大等待时间和锁的超时时间
二.依赖和版本说明
- 整合redisson引入相关的包
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>${version}</version>
</dependency>
- 版本需要注意和springboot的版本需要兼容具体的根据springboot的版本进行选择
- 对于关系可以参考 redisson整合springboot
- 配置项
spring:
redis:
database: #库名
host: #主机名
port: #端口号
password: #密码
ssl: #ssl认证
timeout: #超时时间
cluster:
nodes: #集群的节点
sentinel:
master: #哨兵的mastername
nodes: #节点
参数的具体说明和配置可以参考文档 配置方法
- 使用方法
三.项目集成方案
1.数据库和redis一致性的方案
@Resource
RedissonClient redissonClient;
/**
* rule
*
* @return
* @throws InterruptedException
*/
@GetMapping("/lock")
public String lock() throws InterruptedException {
RLock lock = redissonClient.getFairLock("anyLock");
// 尝试加锁,最多等待10秒,上锁以后10秒自动解锁
lock.lock.tryLock( 10,10, TimeUnit.SECONDS);
try {
log.info("lock 睡眠开始");
//具体的业务操作
Thread.sleep(9000);
log.info("lock 睡眠结束");
} catch (InterruptedException e) {
e.printstacktrace();
} finally {
log.info("lock 主动释放锁");
lock.unlock();
}
return "";
}
2.查询接口获取到最新数据的方案
@GetMapping("/tryLock")
public String tryLock() throws InterruptedException {
RLock lock = redissonClient.getFairLock("anyLock");
if(lock.isLocked()){
// 尝试加锁,最多等待20秒,上锁以后10秒自动解锁
boolean res = lock.tryLock(20, 10, TimeUnit.SECONDS);
log.info("tryLock 方法获取到锁:{}",res);
if (res) {
try {
log.info("tryLock 睡眠开始");
Thread.sleep(9000);
log.info("tryLock 睡眠结束");
} catch (InterruptedException e) {
e.printstacktrace();
} finally {
lock.unlock();
log.info("tryLock 主动释放锁");
}
}else {
log.info("tryLock 方法未获取到锁:{}",res);
}
}else {
//查询接口,未加锁直接获取当前的redis数据
log.info("未加锁直接过去资源");
}
return "";
}
操作工具类(koal.ngaudit.rule.util)
@Slf4j
@Component
public class RedissonLockUtil {
@Resource
RedissonClient redissonClient;
/**
* 主动获取锁,若超时直接返回异常
*
* @param lockName 锁定资源的key
* @param waitTime 获取锁最大等待时间
* @param timeOutTime 超时时间
* @return
* @throws InterruptedException
*/
public boolean tryLock(String lockName,long waitTime,long timeOutTime) throws InterruptedException {
RLock fairLock = redissonClient.getFairLock(lockName);
return fairLock.tryLock( waitTime,timeOutTime, TimeUnit.SECONDS);
}
/**
* 查询时候判断是否可以进行查询操作,若超时直接返回异常
*
* @param lockName 锁定资源的key
* @param waitTime 获取锁最大等待时间
* @param timeOutTime 超时时间
* @return
* @throws InterruptedException
*/
public boolean queryAndTryLock(String lockName, long waitTime, long timeOutTime) throws InterruptedException {
RLock lock = redissonClient.getFairLock(lockName);
if(lock.isLocked()){
return lock.tryLock(waitTime, timeOutTime, TimeUnit.SECONDS);
}else {
log.info("未加锁直接获取资源");
return true;
}
}
四.实现方案设计
1.业务操作数据库和redis的方案
2.业务操作数据库和redis的方案
五.注意事项
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。