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>

2. SpringBoot配置

 1 server:
 2   port: 8081
 3 # Redis数据库索引(默认为04 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

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 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值