package com.example.redistest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@RestController
public class demo {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@GetMapping(value = "/test")
public String testRedisTemp() {
int orderId = 1;
String lockKey = "lockKey" + orderId;
String clientId = UUID.randomUUID().toString();
boolean exit = false;
/**
TODO 这里还需要考虑锁万一在30秒内没有执行完成, 其他线程进入下面的代码(不符合互斥需求)? 怎么办?
解决的办法是之一是 使用redision...
第二个方法是所续命, 在启动一个线程,睡眠总时间的三分之二的时间, 如果睡醒方法结束就就好, 如果还没好则将
key的时候再续上10秒, 或者其他的
*/
Boolean baoxin = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS);
if (!baoxin) {
return "error";
}
// 锁续命 其实这里用定时器更好, 下面算是伪代码, 只能续命一次
new Thread(new Runnable() {
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(20L);
String success = stringRedisTemplate.opsForValue().get(lockKey);
if (!StringUtils.isEmpty(success)){
// 再去redis中获取这个key如果能拿到则代表需要续期,重新设置为30秒,
// 如果拿到为null,则代表已经不需要续期, 已经都跑完并删除key
stringRedisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}}
).start();
try {
// 库存
int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));
if (stock > 0) {
int realStock = stock - 1;
stringRedisTemplate.opsForValue().set("stock", String.valueOf(realStock));
String result = String.format("扣除成功,剩下库存:%d\n", realStock);
System.out.printf(result);
return result;
} else {
String result = "扣除失败,库存不足";
System.out.println(result);
return result;
}
} finally {
// 避免删除了别人的锁
if (clientId.equals(stringRedisTemplate.opsForValue().get(lockKey))) {
stringRedisTemplate.delete(lockKey);
}
}
}
}
redis分布式锁
最新推荐文章于 2025-02-18 10:18:27 发布