一、自己模拟一个分布式锁
/**
* @Description 自己模拟一个分布式锁
* 加锁使用setIfAbsent setnx(setIfPresent setex)
* 值不要写固定字符串 使用大字符串如 UUID
* 解锁使用lua脚本
*/
public Map<String, List<Category2Vo>> getCategoryJsonFromDbWithRedisLock() {
String uuid = UUID.randomUUID().toString();
Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent("lock", uuid, 300, TimeUnit.SECONDS);
if (lock) {
//原子加锁 原子解锁
System.out.println("获取分布式锁成功");
Map<String, List<Category2Vo>> dataFromDb;
try {
//加锁成功 执行业务
dataFromDb = getDataFromDb();
} finally {
String script = "if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" +
"then\n" +
" return redis.call(\"del\",KEYS[1])\n" +
"else\n" +
" return 0\n" +
"end";
stringRedisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class), Arrays.asList("lock"), uuid);
}
//获取值对比 对比成功删除 必须是一个原子操作 lua脚本解锁
// String lockValue = stringRedisTemplate.opsForValue().get("lock");
// if (uuid.equals(lockValue)){
// //如果是自己的锁 删除
// stringRedisTemplate.delete("lock");
// }
return getDataFromDb();
} else {
System.out.println("获取分布式锁失败 等待重试");
try {
Thread.sleep(