分布式锁:满足分布式系统或集群模式下多进程可见,并且互斥的锁
特点:多进程可见、互斥、高可用、高性能、安全性.......
三种常见的实现方式:
接下来使用Redis实现分布式锁
使用SETNX实现互斥 增加过期时间
首先是一个初级版本:
public class SimpleRedisLock implements ILock{
private String name;
private StringRedisTemplate stringRedisTemplate;
private static final String kEY_PREFIX = "lock:";
public SimpleRedisLock(StringRedisTemplate stringRedisTemplate, String name) {
this.stringRedisTemplate = stringRedisTemplate;
this.name = name;
}
@Override
public boolean trylock(long timeoutSec) {
// 获取线程标识
long threadId = Thread.currentThread().getId();
// 获取锁
Boolean success = stringRedisTemplate.opsForValue()
.setIfAbsent(kEY_PREFIX + name, threadId+"", timeoutSec, TimeUnit.SECONDS);
return Boolean.TRUE.equals(success);
}
@Override
public void unlock() {
// 释放锁
stringRedisTemplate.delete(kEY_PREFIX + name);
}
}
// 创建锁对象
SimpleRedisLock lock = new SimpleRedisLock(stringRedisTemplate, "order:" + userId);
// 获取锁
boolean isLock = lock.trylock(5);
if(!isLock) {
// 获取锁失败 返回错误信息或重试
return Result.fail("不允许重复下单!");
}
try {
// 创建代理对象 解决事务问题
IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
return proxy.createVoucherOrder(voucherId);
}finally {
lock.unlock();
}
出现的问题:
线程1释放了线程2的锁