当前位置: 首页 > news >正文

RReadWriteLock读写锁应用场景

背景

操作涉及一批数据,如订单,可能存在多个场景下操作,先使用读锁,从redis缓存中获取操作中数据

比如

关闭账单,
发起调账,
线下结算,
合并支付

先判断当前操作的数据,是否在其他地方操作中(在redis set结构中),

存在:提示稍后再操作,业务流程终止。

不存在:把当前操作数据放入redis 缓存中(同时这个动作加写锁),在加写锁的过程中,是不允许其他读锁读取数据的

然后,进行业务逻辑处理

什么把缓存中数据删除呢?


操作完成,删除缓存中数据(同时加写锁)

    /**
     * 删除操作完成的账单号缓存
     *
     * @param billNoList
     */
    public void removeInOperationBillNoCache(List<String> billNoList) {
        log.info("removeInOperationBillNoCache--->billNoList:{}", JSON.toJSONString(billNoList));
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock(Constant.LEASE_BILL_IN_OPERATION_KEY);
        RLock writeLock = readWriteLock.writeLock();
        writeLock.lock();
        try {
            billNoList.forEach(billNo -> redisService.srem(Constant.LEASE_BILL_IN_OPERATION_CACHE, billNo));
        } finally {
            writeLock.unlock();
        }
    }

 判断及读写锁逻辑

    /**
     * 缓存操作中的账单号
     *
     * @param billNoList
     */
    @SuppressWarnings("unchecked")
    public void inOperationBillNoCache(List<String> billNoList) {
        log.info("inOperationBillNoCache--->billNoList:{}", JSON.toJSONString(billNoList));
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock(Constant.LEASE_BILL_IN_OPERATION_KEY);
        RLock rLock = readWriteLock.readLock();
        rLock.lock();
        try {
            if (redisService.hasKey(Constant.LEASE_BILL_IN_OPERATION_CACHE)) {
                Set<String> inOperationBillNoSet = redisService.smembers(Constant.LEASE_BILL_IN_OPERATION_CACHE);
                log.info("inOperationBillNoCache--->inOperationBillNoSet:{}", JSON.toJSONString(inOperationBillNoSet));
                if (CollectionUtils.isNotEmpty(inOperationBillNoSet)) {
                    List<String> multipleOperationBillNoList = (List<String>) CollectionUtils.intersection(inOperationBillNoSet, billNoList);
                    throw new LeaseServiceException(ErrConstant.INVALID_DATAFILED, String.format("账单[%s]存在多人操作,请刷新后重试", String.join(",", multipleOperationBillNoList)));
                }
            }
        } finally {
            rLock.unlock();
        }

        RLock writeLock = readWriteLock.writeLock();
        writeLock.lock();
        try {
            billNoList.forEach(billNo -> redisService.sadd(Constant.LEASE_BILL_IN_OPERATION_CACHE, billNo));
        } finally {
            writeLock.unlock();
        }
    }

调用场景 

关于缓存数据redis结构选取

set,数据不重复,可以计算交集,判断是否在当前元素中 

源码

 

相关文章:

  • 第五次CCF-CSP认证(含C++源码)
  • 线性回归机器学习
  • 如何打开文件后缀名
  • 基于大模型的小脑扁桃体下疝畸形全流程预测与诊疗方案研究报告
  • 力扣热题 100:堆专题经典题解析
  • 建筑兔零基础自学记录42|cityengine2019导入sketchup/SU 2
  • 架构思维:高性能架构_01基础概念
  • 2025.3.9总结
  • p5.js:sound(音乐)可视化,动画显示音频高低变化
  • 基于定制开发开源AI智能名片S2B2C商城小程序的零售运营策略研究
  • linux安装Mariadb10.5并修改端口
  • Linux基础之Linux常用命令
  • 行式数据库与列式数据库区别
  • 【Linux通信篇】深入理解进程间通信——管道
  • 第八课:性能优化与高并发处理方案
  • Debian二次开发一体化工作站:提升科研效率的智能工具
  • NVIDIA显卡驱动、CUDA、cuDNN 和 TensorRT 版本匹配指南
  • 【大模型】WPS 接入 DeepSeek-R1详解,打造全能AI办公助手
  • 【实战篇】【DeepSeek 全攻略:从入门到进阶,再到高级应用】
  • 《几何原本》命题I.23
  • 做电商网站需要会些什么/郑州网络推广哪家口碑好
  • 电子配件 技术支持 东莞网站建设/网络营销的分类
  • 厦门APP开发网站开发公司/百度搜索引擎属于什么引擎
  • 网站维护管理/营销方式有哪些
  • 做网站布局流程/网页设计素材网站
  • 微信上怎么做网站链接/关键词拓展工具有哪些