问题:
相对于之前的单体项目中的Synchronized锁和lock锁在微服务架构中由于服务之间调用导致Synchronized锁和lock锁失效,而引入分布式锁解决并发问题。
由于redis本身有setnx锁进而解决了微服务多应用调用安全问题。
思路:
将获取的数据放进redis中setnx判断,当下次再次放入的时候如果redis的已经存在就会返回0或1,返回1说明redis中已经存在,返回0说明redis中不存在,
基于此可以运用这个特性。
以下面的java代码为例(写的很简洁),将数据放进redis中setnx判断,如果返回true说明添加成功,返回false则说明相同key中value已经存在因此会返回false。
判断这个时候的返回值true进入设置过期时间(防止程序宕机出现死锁),执行逻辑代码,最后删除锁释放资源,
判断为false进入else休眠加锁重试(休眠时间不易过长,毕竟安全范围内效率也是很重要的,建议10-100ms之间)。
java代码:
@PostMapping("/redis/{redisId}")
public CommonResult<JobslipCall> redistemp(@PathVariable("redisId")String redisId) {
Boolean setnx = redisTemplate.opsForValue().setIfAbsent("setnx"+redisId, "");
if(setnx){
redisTemplate.expire("setnx"+redisId,60, TimeUnit.SECONDS);
/**
* 业务逻辑代码
*/
//删除锁 释放资源
Boolean delete = redisTemplate.delete("setnx" + redisId);
}else{
try {
//休眠一秒
Thread.sleep(1000);
//加锁失败重试
redistemp(redisId);
}catch (Exception e){
log.error("500",e);
}
}
return CommonResult.success();
}
<!--redis依赖配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
![]()