分布式——分布式锁

 本质是利用redis的setnx()方法的特性来加锁,setnx()即key不存在则设置key,否则直接返回false,要求在分布式系统中使用同一个redis服务,以下提供两种解决方案:
 1、直接使用redisTemplate:这其实并不能完全保证高并发下的安全问题,因为可能在锁过期之后该线程尚未执行完,这时其他线程是可以进入到同步代码中的,因此还需要开启一个守护线程来延续过期时间

public class SyncLock{

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public String syncStock() {
        String lockKey = "lockKey";
        String clientId = UUID.randomUUID().toString();
        try {
            //将设置key值和超时时间作为原子操作,低版本的redisTemplate不支持该方法
            Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 10, TimeUnit.SECONDS);
            if (!result)
                return "error";
            int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));//获取库存
            if (stock > 0) {
                int realStock = stock - 1;
                stringRedisTemplate.opsForValue().set("stock", realStock + "");
            } else {
                return "库存不足!";
            }
        } finally {
            if (clientId.equals(stringRedisTemplate.opsForValue().get(lockKey)))
                stringRedisTemplate.delete(lockKey);//同时各个线程释放各自加的锁
        }
        return "成功!";
    }
}

 2、使用redisson:redisson会自动为我们开启守护线程延长锁的时间

public class SyncLock{

    @Autowired
    private Redisson redisson;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public String syncStock() {
        String lockKey = "lockKey";
        RLock lock = redisson.getLock(lockKey);
        try {
            lock.tryLock();
            int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));//获取库存
            if (stock > 0) {
                int realStock = stock - 1;
                stringRedisTemplate.opsForValue().set("stock", realStock + "");
            } else {
                return "库存不足!";
            }
        } finally {
            lock.unlock();
        }
        return "成功!";
    }
}

  redisson的原理示意图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值