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数据库索引(默认为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
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 }