阿里云个人服务器搭建项目笔记八:使用Redis实现分布式锁

因为应用程序服务器有两台,所以如果仅仅在每台机器上面同步时不够的,因为获取到的不是同一把锁。

这里使用redis实现分布式锁

注意事项

使用redis作为分布式锁要注意几点:

原理:在redis上面定义一个锁的key,每台应用程序服务器的下单请求先要去redis尝试创建一个锁的key,如果锁的key已经存在,那么说明其他线程已经进入,这个线程就阻塞。如果锁的key不存在,那么就说明锁是可以获取的状态,建立这个key从而获取锁。

注意事项一:产生异常情况如何保证锁的释放
答:利用try finally,try里面放下单流程,finally里面删除key,保证异常情况下也能释放锁。

注意事项二:服务器断电之后,锁一直存在怎么办?
答:设置过期时间,注意!redis的2.6之前的版本,设置锁的key、设置过期时间这两步操作不是原子性的!但是在2.6之后,可以用一行代码设置key并设置过期时间保证原子性。下面会介绍。

注意事项三:如何保证线程释放的是自己加上的锁?
答:加锁的key的时候,value设置为一个随机的uuid,等到删除key的时候,先判断缓存中value是不是这个uuid,如果是再释放。

注意事项四:程序执行时间过长,超过了key的过期时间怎么办?
开一个守护线程,先休眠,然后不断去判断当前线程是否还有持有锁,如果持有而且超时时间到,就给他“续命”,加上一段时间,直到线程自己删掉key释放锁。

其他方式

因为我的redis只有一台,如果redis也部署了主从,那么无法完全保证可靠性。因为分布式锁只会去验证主redis的加锁情况。而不会去验证从redis的key的情况。
但是zookeeper是有全部主从分布式锁的验证的,所以zookeeper比较能保证安全,但是相对于redis的实现方式效率较低。

redis实现的方式可以使用redisson框架直接实现

代码

这里以减库存为例,方式超卖现象

 @Transactional
    public boolean decreaseStock(Integer itemId, Integer amount) throws BusinessException {
        //int affectedRow = itemStockDOMapper.decreaseStock(itemId, amount);
        //result是代表执行完扣减库存操作之后的结果(还剩多少)
        String lockValue = UUID.randomUUID().toString();
        Boolean lockSuccess = redisTemplate.opsForValue().setIfAbsent("lockKey", lockValue, 5, TimeUnit.SECONDS);
        if(lockSuccess){
            try {
                long result = redisTemplate.opsForValue().increment("kill_item_stock"+itemId, amount.intValue()*-1);
                if(result >= 0){
                    //更新库存成功
                    return true;
                }else{
                    //更新库存失败
                    return false;
                }
            }
            finally {
                if(redisTemplate.opsForValue().get("lockKey").equals(lockValue)){
                    redisTemplate.delete("lockKey");
                }
            }
        }else return false;

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值