讲解一下redisson分布式锁

很多人喜欢把redisson继续封装成注解,不说好坏,只想说锁得粒度还是越小越好。
项目中引入包

版本使用3.11.1

<dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
        </dependency>

配置文件添加

spring.redis.cluster.nodes = xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx
spring.redis.password = passwd

示例①

@Autowired
private RedissonClient redissonClient;
public void lockTest(){
    RLock lock = redissonClient.getLock(RedisConst.LOCK_PREFIX+"lock:order:xxxxxx");
    try {
        // 这里要根据实际业务使用isLocked()
        if (lock.tryLock(5,30, TimeUnit.SECONDS)) {
            //todo 这里实现你的业务逻辑,锁使用原则,粒度越小越好
        }
    } catch (InterruptedException e) {
        System.out.println("获取锁异常");
    }finally {
        lock.unlock();
    }
}

示例②乐观锁场景

RLock lock = redissonClient.getLock(RedisConst.LOCK_PREFIX + "COMMIT_LOCK");
        boolean res=false;
        try {
            res = lock.tryLock(0, 10, TimeUnit.SECONDS);
            System.out.println(res);
            if (res){
                System.out.println("获取到锁了");
            }
            if (!res) {
                return BusinessResultModel.fail("操作太频繁!");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }

trylock参数说明

  • -- waitTime:第一个参数最长等待取锁时间。如果再这个时间内取到锁将返回true,如果超过这个时间还没取到锁将返回false

  • -- leastTime: 第二个参数,取到锁之后锁过期时间,当超过这个时间还没执行完业务锁将被释放。

  • -- TimeUnit: 第三个参数,时间单位。

由于代码业务得复杂性,会存在以下情况:

  • 1、三个线程并发得情况下,我们假设线程A、B、C
    A线程获取锁,B线程进来取不到锁,这个时候B线程执行到finally方法把A的锁释放了,这个时候C线程去取锁取到锁了,那么AC线程同时执行同一段代码。

解决方案:实际上不存在这个问题,因为在redisson中锁只能由当前取到锁得线程释放了,所以调用lock.unlock()不用在加判断了。

  • 2、AB两个线程非并发执行,假设A线程执行完成返回后,B线程进来了,执行了同一段代码,实际上AB两个线程是同一个请求内容。这实际是一个幂等问题。

这个时候会由于业务问题导致数据库出现脏数据。例如根据同一个订单号去生成付款单,那么将会生成两条id不一样的付款单。

解决方案:针对相同请求通过业务进行判断,以上述例子为例:条件为同一个订单号,判断该订单是否已处理,如果已处理,则直接返回处理成功。或者返回已处理。

  • 3、根据trylock的参数我们可以知道,如果我想立马获得取锁结果,只要将第一个参数设置为0即可
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转自:https://github.com/angryz/my-blog/issues/4[https://git...
    王帅199207阅读 12,405评论 0 23
  • 实现Redis的分布式锁,除了自己基于redis client原生api来实现之外,还可以使用开源框架:Redis...
    大笨群阅读 5,955评论 1 9
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,581评论 16 22
  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    迷月闪星情阅读 10,619评论 0 11
  • 可爱进取,孤独成精。努力飞翔,天堂翱翔。战争美好,孤独进取。胆大飞翔,成就辉煌。努力进取,遥望,和谐家园。可爱游走...
    赵原野阅读 2,791评论 1 1