1.基于SpringBoot实现分布式锁
1.依赖
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.配置redis连接
spring.redis.database=4
spring.redis.client-name=jiuyue
spring.redis.port=6379
spring.redis.host=127.0.0.1
spring.redis.password=zsq2170
3.代码
@Autowired
private StringRedisTemplate redisTemplate;
@ApiOperation(value = "基于Springboot redis分布式锁")
@GetMapping("/select/list1")
public String deductStock1() {
String lockKey = "product_001";
String clientId= UUID.randomUUID().toString(); //每一个线程进来的唯一标识
try{
// Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, "zhang");//jedis.setnx(key,value)
// redisTemplate.expire(lockKey,10, TimeUnit.SECONDS);
//key设置超时时间,10秒过期,防止程序突然崩溃导致死锁 jedis.setnx(key,value ,10,秒)
Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, clientId,10, TimeUnit.SECONDS);//jedis.setnx(key,value)
if (!result) {
return "error"; //错误返回
}
int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock")); //jedis.get("stock")
if (stock > 0) {
int realStock = stock - 1;
redisTemplate.opsForValue().set("stock", realStock + ""); //jedis.set("key","value")
System.out.println("扣减成功,剩余库存:" + realStock + "");
} else {
System.out.println("扣减失败,库存不足");
}
}finally {
//redis释放锁必须是当前线程的锁 防止redis提前失效 ,造成3号的锁被2号释放掉,循环失效
if (clientId.equals(redisTemplate.opsForValue().get(lockKey))) {
redisTemplate.delete(lockKey); //释放锁 防止程序异常出现死锁
}
}
return "end";
}
2.基于Redisson框架实现分布式锁
1.依赖
<!--redisson框架-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.6.5</version>
</dependency>
2.配置代码
@Configuration
public class RedisConfig {
//单redis连接 start
Config redissonConfig = new Config();
SingleServerConfig singleServerConfig = redissonConfig.useSingleServer();
singleServerConfig.setAddress("redis://47.99.212.21:6379");
singleServerConfig.setPassword("zsq2170");
// 设置redis几号数据库
singleServerConfig.setDatabase(4);
singleServerConfig.setClientName("jiuyue");
singleServerConfig.setConnectTimeout(10000);
singleServerConfig.setConnectionPoolSize(300);
return Redisson.create(redissonConfig);
//单redis连接 end
}
}
3.实现代码
@Autowired
private Redisson redisson;
@ApiOperation(value = "基于Redisson框架实现 redis分布式锁")
@GetMapping("/select/list2")
public String deductStock2() {
String lockKey = "product_001";
RLock redissonLock = redisson.getLock(lockKey);//获取锁
try{
redissonLock.lock(30,TimeUnit.SECONDS); //设置超时时间
int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock")); //jedis.get("stock")
if (stock > 0) {
int realStock = stock - 1;
redisTemplate.opsForValue().set("stock", realStock + ""); //jedis.set("key","value")
System.out.println("扣减成功,剩余库存:" + realStock + "");
} else {
System.out.println("扣减失败,库存不足");
}
}finally {
redissonLock.unlock(); //释放锁
}
return "end";
}