首页 > 数据库 >分布式锁 -- redis

分布式锁 -- redis

时间:2023-02-28 20:12:54浏览次数:45  
标签:String -- invoiceVo req redis isAccess 分布式

原理

redis设置一个key和value,如果存在则获取锁失败,不存在则获取锁成功处理业务,业务处理完成后删除这条数据,可以带个失效时间。

 

代码

public void handleInvoice(SubmitInvoiceRpcReq req) throws Exception {
        boolean isAccess = false;
        String invoiceKey = String.format(ApiRedisKey.AGENT_WITHDRAW_INVOICE, req.getBaseUserId());
        try {
            isAccess = redisTemplate.setIfAbsent(invoiceKey, "1", 60);
            JlpayAssert.isTrue(isAccess, "正在处理,稍后再试");
            //批处理ID(时间戳+用户ID)
            String batchNo = System.currentTimeMillis() + String.format("%010d", req.getBaseUserId());
            InvoiceVo invoiceVo = new InvoiceVo();
            invoiceVo.setBatchNo(batchNo);
            invoiceVo.setLicenseNo(getLicenseNo(req.getBaseUserId()));
            HashMap<String, String> channelMap = getChannelMap();
            invoiceService.saveSubmitInvoice(req, channelMap, invoiceVo);
            FixedThreadPoolUtil.INSTANCE.execute(() -> {
                log.info("提现开票异步任务--开始");
                List<WithdrawInvoice> withdrawInvoiceList = invoiceService.getWithdrawInvoiceList(batchNo);
                if (CollectionUtils.isEmpty(withdrawInvoiceList)) {
                    return;
                }
                invoiceService.handleSubmitInvoice(withdrawInvoiceList);
                withdrawInvoiceList.stream().forEach(withdrawInvoice -> {
                    InvoiceVo vo = makeupInvoiceVo(withdrawInvoice);
                    sendInvoiceEmail(vo, withdrawInvoice);
                });
                log.info("提现开票异步任务--结束");
            });
        } finally {
            if (isAccess) {
                redisTemplate.delete(invoiceKey);
            }
        }
    }

 

锁失效原因

1. 删除锁之前发生异常

client1 获取到锁A,执行业务操作,这个时候服务发生异常,没有删除锁,导致别人无法操作。   

方案: 设置过期时间

2. 过期时间到了,业务没执行完

client1 获取到锁A设置失效时间为十秒,执行业务操作花了20秒才处理完,但是锁已经不在了。

方案:可以把失效时间设置长点,但会影响性能

 

Redission架构

使用Lua脚本对redis进行加锁操作,确保业务执行的原子性。

看门狗会每隔10s检查客户端是否还持有锁,如果还持有就会延迟key的生存时间。

 

参考:https://www.cnblogs.com/AnXinliang/p/10019389.html

https://baijiahao.baidu.com/s?id=1730716661153081344&wfr=spider&for=pc

 

标签:String,--,invoiceVo,req,redis,isAccess,分布式
From: https://www.cnblogs.com/zhougongjin/p/17165798.html

相关文章

  • 处理 S4过账时的错误:“更正统一日记账分类账的定制设置”
    1.S4HANA环境新配置的公司代码,做凭证时报错:2. 点开后报错:  3. 分别点击提示事务  检查分类账设置路径:IMG->财务会计->财务会计全局设置->分类账->分类账-......
  • 云原生数据库TDSQL-C 容灾的实践和探索
    云原生数据库TDSQL-C作为腾讯云架构平台部核心数据库产品之一,致力于为云上ToB用户和公司自研业务提供集高性能、低成本、大存储、低延迟、秒级扩缩容、极速回档、Serverles......
  • SpringBoot整合Spring Security
    1快速入门在项目中直接引入SpringSecurity的依赖<!--springSecurity--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-bo......
  • 2月28号总结
    7.1类与对象类定义一种全新的数据类型,包含一组变量和函数;对象是类这种类型对应的实例。例如在一间教室中,可以将Student定义成类,表示“学生”这个抽象的概念。那么每个同学......
  • 7 回溯算法理论基础
    回溯法:也可以叫做回溯搜索法,它是一种搜索的方式。在二叉树系列中,已经不止一次,提到了回溯,回溯是递归的副产品,只要有递归就会有回溯。回溯法的效率:回溯的本质是穷举,穷举所有......
  • C++里的memset
    memset函数是内存赋值函数,用来给某一块内存空间进行赋值的;包含在<string.h>头文件中,可以用它对一片内存空间逐字节进行初始化;原型为:void*memset(void*s,intv,......
  • 技术分担产品之忧(上):挑选有业务专家潜力的人
    你好,我是王植萌,去哪儿网的高级技术总监、TC主席。从2014年起,担任一个部门的技术负责人,有8年技术总监经验、5年TC主席的经验。这节课我会从去哪儿网产研融合的经验出发,和你聊......
  • 【Azure 存储服务】Azure Storage Account 下的 Table 查询的性能调优
    问题描述AzureStorageAccount下的Table查询的性能调优?问题解答因为AzureStorageTable服务(表服务)与常规的关系型数据库不一样(例如:MySQL,SQLServer等),他里面存储的......
  • mysql数据库的主主复制和半同步复制
    今天分享的是mysql数据库的主主复制和半同步复制的一系列步骤,以及在各处出现错误的解决方法和其在操作过程中需要注意的地方范例:主主复制主主复制:两个节点,都可以更新数据,并......
  • 软件授权赋能餐饮企业加速向上
     AI识别选餐,自动称重计价,人脸识别支付,档口自助取餐……相信很多人都体验过这样的食堂,这样的智慧食堂越来越多,逐步开始重构餐饮消费体验。然而,食堂的数字化转型尚处于发展阶......