redis分布式鎖學習之路1-RedisTemplate實現分布式鎖


1. pom文件

 1 <parent>
 2     <groupId>org.springframework.boot</groupId>
 3     <artifactId>spring-boot-starter-parent</artifactId>
 4     <version>2.1.4.RELEASE</version>
 5     <relativePath/> <!-- lookup parent from repository -->
 6 </parent>
 7 
 8 <dependencies>
 9     <dependency>
10         <groupId>org.springframework.boot</groupId>
11         <artifactId>spring-boot-starter-web</artifactId>
12     </dependency>
13     <dependency>
14         <groupId>org.springframework.boot</groupId>
15         <artifactId>spring-boot-starter-test</artifactId>
16         <scope>test</scope>
17     </dependency>
18     <dependency>
19         <groupId>org.springframework.boot</groupId>
20         <artifactId>spring-boot-starter-data-redis</artifactId>
21     </dependency>
22 </dependencies>
View Code

2. SpringBoot配置.

 1 server:
 2   port: 8081
 3 # Redis數據庫索引(默認為0)
 4 spring:
 5   redis:
 6     database: 0
 7     # Redis服務器地址
 8     host: 127.0.0.1
 9     # Redis服務器連接端口
10     port: 6379
11     # Redis服務器連接密碼(默認為空)
12     #password:
13     jedis:
14       pool:
15         max-idle: 8
16         # 連接池最大阻塞等待時間(使用負值表示沒有限制)
17         max-wait: -1
18         # 連接池中的最大空閑連接
19         # 連接池中的最小空閑連接
20         min-idle: 0
21     # 連接超時時間(毫秒)
22     timeout: 100000
View Code

3. 話不多說,直接代碼擼起

 

 1 package com.hy.redis.controller;
 2 
 3 import org.springframework.data.redis.core.RedisTemplate;
 4 import org.springframework.scheduling.annotation.Async;
 5 import org.springframework.stereotype.Controller;
 6 import org.springframework.web.bind.annotation.RequestMapping;
 7 import org.springframework.web.bind.annotation.ResponseBody;
 8 
 9 import javax.annotation.Resource;
10 import java.util.Objects;
11 import java.util.UUID;
12 import java.util.concurrent.Executors;
13 import java.util.concurrent.ScheduledExecutorService;
14 import java.util.concurrent.TimeUnit;
15 
16 /**
17  *
18  * redis 加鎖的方式 實現高並發小分布式事務的處理
19  *
20  * @author huheng
21  * @date 2020/08/03
22  **/
23 @Controller
24 public class DeductStockController {
25 
26     @Resource
27     private RedisTemplate redisTemplate;
28 
29     @RequestMapping("/deduct-stock")
30     @ResponseBody
31     public String deductStock() {
32         String clientId = UUID.randomUUID().toString();
33         String lockKey = "lockKey";
34         try {
35             // 先加鎖
36             Boolean flag = redisTemplate.opsForValue().setIfAbsent("lockKey", clientId, 10, TimeUnit.SECONDS);
37 
38             // 加鎖成功 執行扣除庫存
39             if (flag) {
40                 // 執行定時器 判斷鎖是否存在 存在 則延長失效時間
41                 timer(lockKey, clientId);
42 
43                 // 讀取庫存
44                 Integer stock = (Integer) redisTemplate.opsForValue().get("stock");
45                 if (stock != null && stock > 0) {
46                     redisTemplate.opsForValue().set("stock", stock - 1);
47                     System.out.println("搶購成功--扣除庫存成功" + "-----原庫存:" + stock + "剩余庫存:" + (stock - 1));
48                 }
49             }
50         } finally {
51             // 釋放鎖
52             String verfiy = (String) redisTemplate.opsForValue().get(lockKey);
53             // 判斷是否為當前線程加的鎖
54             if (Objects.equals(verfiy, clientId)) {
55                 redisTemplate.delete(lockKey);
56             }
57         }
58         return "end";
59     }
60 
61     /**
62      * 5秒鍾一次
63      * @param lockKey
64      * @param clientId
65      */
66     @Async
67     public void timer(String lockKey, String clientId) {
68         ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
69         // 參數:1、任務體 2、首次執行的延時時間
70         //      3、任務執行間隔 4、間隔時間單位
71         service.scheduleAtFixedRate(()->{
72             String result = (String) redisTemplate.opsForValue().get(lockKey);
73             if (result != null && result.equals(clientId)) {
74                 redisTemplate.expire(lockKey, 10 , TimeUnit.SECONDS);
75             } else {
76                 service.shutdown();
77             }
78         }, 0, 5, TimeUnit.SECONDS);
79     }
80 }
View Code


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM