redis 构建分布式锁
redis 构建分布式锁
-----------2020/03.04
能够被多个线程访问的共享数据,为了实现数据的准确性(一致性),必须考虑加锁。
实质是通过redis的setnx去实现锁的机制。
SET if Not eXists ----->sentnx
-------看例子
先设置set goods_num 100
把商品数量定为100
然后基于两个一样的程序去抢资源,我们来看下会有什么结果:
@Component
public class DistributedLock {
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 获得锁
* @param lockId
* @param millisencond
* @return boolean
*/
public boolean getLock(String lockId, long millisencond) {
Boolean success = redisTemplate.opsForValue().setIfAbsent(lockId, "lock",
millisencond, TimeUnit.MILLISECONDS);
return success != null && success;
}
public void releaseLock(String lockId) {
redisTemplate.delete(lockId);
}
public String getValueByKey(String key) {
String value = redisTemplate.opsForValue().get(key);
return value;
}
public void setValueByKey(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
}
@Component
public class BusinessTask {
private final static String LOCK_ID = "happyjava";
@Autowired
DistributedLock distributedLock;
@Scheduled(cron = "0/10 * * * * ? ")
public void doSomething() {
boolean lock = distributedLock.getLock(LOCK_ID, 10 * 1000);
if (lock) {
Integer num = Integer.parseInt(distributedLock.getValueByKey("goods_num"));
if(num > 0) {
System.out.println("task1----->执行任务");
distributedLock.setValueByKey("goods_num", Integer.toString(num - 1));
System.out.println("商品数剩余----->" + (num - 1));
} else {
System.out.println("task1----->对不起,商品已经卖完,结束");
}
distributedLock.releaseLock(LOCK_ID);
} else {
System.out.println("task1----->没有抢到锁");
}
}
}
然后基于spring boot 另外再启一个同样的程序,端口不一致而已,我们截图来看下结果:


看到没有,抢到锁的,进行商品减1操作,没有抢到的只能等待了。
没有发生同时操作相同库存的情况。
---------完毕---------
那大家想一下,为什么很多公司不直接使用这种方式,而是使用类似于redisson这种玩意来实现分布式锁??
浙公网安备 33010602011771号