一、简述
二、存在问题
1、死锁、原子性问题
2、业务执行时间超时
3、锁误删
4、锁续命
三、解决措施
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.11.1</version>
</dependency>
</dependencies>
redission配置类
@Configuration
public class RedissionConfig {
@Bean
public Redisson getRedission(){
Config config = new Config();
config.useSingleServer().setAddress("redis://localhost:6379").setPassword("root");
Redisson redisson = (Redisson) Redisson.create(config);
return redisson;
}
}
1、
public String deductStock() {
String lockKey = "lockKey";
//当前线程唯一标识 防止误删其他线程的措
String clientId = UUID.randomUUID().toString();
try {
//设置锁 原子性和死锁
Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 10, TimeUnit.SECONDS);
/*
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Long expire = redisTemplate.getExpire(lockKey, TimeUnit.SECONDS);
if(expire < 3){
redisTemplate.expire(lockKey,10,TimeUnit.SECONDS);
}
};
},5);
*/
if(!result){
return "error code";
}
int stockNum = Integer.parseInt(redisTemplate.opsForValue().get("stock"));
if (stockNum > 0) {
int realStock = stockNum - 1;
redisTemplate.opsForValue().set("stock",realStock+"");
System.out.println("扣减库存成功,剩余库存为:"+realStock);
} else {
System.out.println("扣减库存失败");
}
} finally {
// 释放锁 防止死锁
if(clientId.equals(redisTemplate.opsForValue().get(lockKey))){
redisTemplate.delete(lockKey);
}
}
return "ok";
}
2、
@GetMapping("/deductStock")
public String deductStock() {
String lockKey = "lockKey";
//当前线程唯一标识 防止误删其他线程的措
String clientId = UUID.randomUUID().toString();
RLock lock = redisson.getLock(lockKey);
try {
lock.lock();
int stockNum = Integer.parseInt(redisTemplate.opsForValue().get("stock"));
if (stockNum > 0) {
int realStock = stockNum - 1;
redisTemplate.opsForValue().set("stock",realStock+"");
System.out.println("扣减库存成功,剩余库存为:"+realStock);
} else {
System.out.println("扣减库存失败");
}
} finally {
// 释放锁 防止死锁
if(clientId.equals(redisTemplate.opsForValue().get(lockKey))){
redisTemplate.delete(lockKey);
}
}
return "ok";
}