原理

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

分布式锁 -- redis的更多相关文章

  1. 分布式锁--Redis小试牛刀

    参考文章: Redis分布式锁的正确实现方式 分布式锁看这篇就够了 在这两篇文章的指引下亲测 Redis分布式锁 引言 分布式系统一定会存在CAP权衡问题,所以才会出现分布式锁 什么是CAP理论? 为 ...

  2. 分布式锁----Redis实现

    分布式锁 为什么需要有分布式锁呢,在单点的时候synchronized 就能解决,但是服务拆分之后,每个服务都是单独的机器,无法解决,所以出现了分布式锁,其实也就是用各种手段,实现获取唯一锁,别人无法 ...

  3. Redis除了做缓存--Redis做消息队列/Redis做分布式锁/Redis做接口限流

    1.用Redis实现消息队列 用命令lpush入队,rpop出队 Long size = jedis.lpush("QueueName", message);//返回存放的数据条数 ...

  4. java-spring基于redis单机版(redisTemplate)实现的分布式锁+redis消息队列,可用于秒杀,定时器,高并发,抢购

    此教程不涉及整合spring整合redis,可另行查阅资料教程. 代码: RedisLock package com.cashloan.analytics.utils; import org.slf4 ...

  5. 分布式锁redis

    1. 首先看这篇文章中  https://mp.weixin.qq.com/s/s-ozSjM5WmSUopxttSWYeQ 为什么redis能实现锁功能呢,看下图,redis命令窗口中,setnx  ...

  6. 分布式锁-Redis方案

    #!/usr/bin/env python # coding=utf-8 import time import redis class RedisLock(object): def __init__( ...

  7. Lua脚本在redis分布式锁场景的运用

    目录 锁和分布式锁 锁是什么? 为什么需要锁? Java中的锁 分布式锁 redis 如何实现加锁 锁超时 retry redis 如何释放锁 不该释放的锁 通过Lua脚本实现锁释放 用redis做分 ...

  8. Redis 分布式锁的实现

    0X00 测试环境 CentOS 6.6 + Redis 3.2.10 + PHP 7.0.7(+ phpredis 4.1.0) [root@localhost ~]# cat /etc/issue ...

  9. 分布式交易系统的并发处理, 以及用Redis和Zookeeper实现分布式锁

    交易系统 交易系统的数据结构 支付系统API通常需要一个“订单号”作为入参, 而实际调用API接口时使用到的往往不是真正意义的业务订单号, 而是交易订单号.  支付系统的API会使用“商户号+订单号” ...

  10. 基于zookeeper或redis实现分布式锁

    前言 在分布式系统中,分布式锁是为了解决多实例之间的同步问题.例如master选举,能够获取分布式锁的就是master,获取失败的就是slave.又或者能够获取锁的实例能够完成特定的操作. 目前比较常 ...

随机推荐

  1. 【KAWAKO】MNN-1.2.0版本交叉编译遇到的错误与解决方法

    目录 在使用gcc-linaro-7.5.0-aarch64-linux-gnu.gcc-linaro-6.3.1-aarch64-linux-gnu交叉编译链对MNN1.2.0进行交叉编译的过程中, ...

  2. 几种排序(c#实现)

    代码: int[] arr = { 2, 3, 4, 6, 1, 5, 4 }; // 冒泡排序:把最小的往前冒 O(n2) //int temp1; //for (int i = 0; i < ...

  3. Vue 非单文件组件(不常用)3步骤(创建、注册、使用)和几个注意点、组件的本质(VueComponent)

    Vue中使用组件的三大步骤: 1.定义组件(创建) 2.注册组件 3.使用组件(写组件标签) 一.如何定义一个组件? 使用Vue.extend(options)创建,其中options 和 new V ...

  4. ansible 离线部署

    1.安装 python 环境 wget https://mirrors.bfsu.edu.cn/anaconda/archive/Anaconda3-2022.10-Linux-x86_64.sh s ...

  5. k8s之pod的生命周期

    pod生命周期 和一个个独立的应用容器一样,Pod 也被认为是相对临时性(而不是长期存在)的实体. Pod 会被创建.赋予一个唯一的 ID(UID),并被调度到节点,并在终止(根据重启策略)或删除之前 ...

  6. Mysql习题系列(二):多表查询(一篇学会做Mysql多表查询题,超详细~)

    Mysql8.0习题系列 软件下载地址 提取码:7v7u 数据下载地址 提取码:e6p9 文章目录 Mysql8.0习题系列 1.多表查询1 1.1题目 1.2答案 1.显示所有员工的姓名,部门号和部 ...

  7. scrapy_redis 分布式爬取酷狗音乐

    目录 声明 安装scrapy_redis 创建scrapy项目 spider模块 items模块.pipelines模块 setting.py 调试 运行 成果图 源码 声明 文章仅供学习交流使用,切 ...

  8. 代码随想录训练营day 4|链表基础理论,移除链表元素,设计链表,反转链表

    链表理论基础 链表是一种由指针串联在一起的线性结构,每一个节点都由一个数据域和一个指针域组成. 链表的类型有:单链表.双链表.循环链表. 链表的存储方式:在内存中不连续分布. 链表的定义很多人因为不重 ...

  9. 前端面试题 10 个「有用」JavaScript 代码片段

    携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情 降低阅读负担,启发创作心智,轻松学习 JavaScript 技巧,日拱一卒,jym,冲~ 注:本篇可能更 ...

  10. unity 扇形范围检测目标

    第一种 代码方法 传入目标点测试即可 private float ScopeDistance = 2f;//扇形距离 private float ScopeJiaodu = 120;//扇形的角度 / ...