1、起初
引入依賴
<!-- spring boot redis緩存引入 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
controller層
/**
* @author lj on 2021/2/28.
* @version 1.0
*/
public class IndexController {
@Autowired
private StringRedisTemplate redisTemplate;
@RequestMapping("/test")
public String testRedisDis(){
final Boolean res = redisTemplate.opsForValue().setIfAbsent("lock_key", "liujun");
if(!res){
return "error";
}
/**
* 執行代碼業務
*/
return "end";
}
}
思考?帶來一系列的問題:
1、系統宕機,未釋放鎖即死鎖(redis設置過期時間,增加try...finally...代碼段)
2、業務時間太長,釋放別人的鎖(設置redis值為唯一uuid;在釋放鎖時(redisTemplate.delete("key"),增加邏輯判斷只能釋放自己的鎖);增加看門狗來續時)
3、保證redis操作的原子性(redis設置值和設置過期時間必須同步)
2、進一步優化:
controller層
/**
* @author lj on 2021/2/28.
* @version 1.0
*/
public class IndexController {
@Autowired
private StringRedisTemplate redisTemplate;
@RequestMapping("/test")
public String testRedisDis(){
String lock_key = "prodect_001";
final String vaule = UUID.randomUUID().toString();
try{
final Boolean res = redisTemplate.opsForValue().setIfAbsent(lock_key, vaule,30, TimeUnit.SECONDS); //保證redis的原子性,設置時長防止redis死鎖
if(!res){
return "error";
}
//TODO 開辟一個分線程使用定時器進行redis續時
/**
* 執行代碼業務
*/
}finally {
//釋放鎖
if(vaule.equals(redisTemplate.opsForValue().get(lock_key))){ //防止釋放別人的鎖
redisTemplate.delete("lock_key");
}
return "end";
}
}
}
3、使用Redisson框架
1、引入Redisson的依賴
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.6.5</version>
</dependency>
2、配置為單機模式
@Bean
public Redisson redisson(){
//此為單機模式
final Config config = new Config();
config.useSingleServer().setAddress("127.0.0.1:6379").setDatabase(0);
return (Redisson) Redisson.create(config);
}
3、簡單的使用代碼片段

整個流程:

watch dog自動延期機制
客戶端1加鎖的鎖key默認生存時間才30秒,如果超過了30秒,客戶端1還想一直持有這把鎖,怎么辦呢?
簡單!只要客戶端1一旦加鎖成功,就會啟動一個watch dog看門狗,他是一個后台線程,會每隔10秒檢查一下,如果客戶端1還持有鎖key,那么就會不斷的延長鎖key的生存時間。
如果時集群的話還有一個問題:就是redis的master節點宕機了,而鎖沒來得及復制到slave節點(待處理。。。)
總結:redisson框架其實就是上面redis過程的優化;
先拿setnx來爭搶鎖,搶到之后,再用expire給鎖加一個過期時間防止鎖忘記了釋放;搶到鎖后會開辟一個分線程看門狗去續時,最后在finally代碼快中刪除鎖。
