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这种玩意来实现分布式锁??

 

posted on 2020-03-04 16:26  Jason_LZP  阅读(305)  评论(0)    收藏  举报