分布式锁 -- redis

原理

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

 

posted on   周公  阅读(16)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示