分布式锁 -- 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
分布式锁 -- redis的更多相关文章
- 分布式锁--Redis小试牛刀
参考文章: Redis分布式锁的正确实现方式 分布式锁看这篇就够了 在这两篇文章的指引下亲测 Redis分布式锁 引言 分布式系统一定会存在CAP权衡问题,所以才会出现分布式锁 什么是CAP理论? 为 ...
- 分布式锁----Redis实现
分布式锁 为什么需要有分布式锁呢,在单点的时候synchronized 就能解决,但是服务拆分之后,每个服务都是单独的机器,无法解决,所以出现了分布式锁,其实也就是用各种手段,实现获取唯一锁,别人无法 ...
- Redis除了做缓存--Redis做消息队列/Redis做分布式锁/Redis做接口限流
1.用Redis实现消息队列 用命令lpush入队,rpop出队 Long size = jedis.lpush("QueueName", message);//返回存放的数据条数 ...
- java-spring基于redis单机版(redisTemplate)实现的分布式锁+redis消息队列,可用于秒杀,定时器,高并发,抢购
此教程不涉及整合spring整合redis,可另行查阅资料教程. 代码: RedisLock package com.cashloan.analytics.utils; import org.slf4 ...
- 分布式锁redis
1. 首先看这篇文章中 https://mp.weixin.qq.com/s/s-ozSjM5WmSUopxttSWYeQ 为什么redis能实现锁功能呢,看下图,redis命令窗口中,setnx ...
- 分布式锁-Redis方案
#!/usr/bin/env python # coding=utf-8 import time import redis class RedisLock(object): def __init__( ...
- Lua脚本在redis分布式锁场景的运用
目录 锁和分布式锁 锁是什么? 为什么需要锁? Java中的锁 分布式锁 redis 如何实现加锁 锁超时 retry redis 如何释放锁 不该释放的锁 通过Lua脚本实现锁释放 用redis做分 ...
- Redis 分布式锁的实现
0X00 测试环境 CentOS 6.6 + Redis 3.2.10 + PHP 7.0.7(+ phpredis 4.1.0) [root@localhost ~]# cat /etc/issue ...
- 分布式交易系统的并发处理, 以及用Redis和Zookeeper实现分布式锁
交易系统 交易系统的数据结构 支付系统API通常需要一个“订单号”作为入参, 而实际调用API接口时使用到的往往不是真正意义的业务订单号, 而是交易订单号. 支付系统的API会使用“商户号+订单号” ...
- 基于zookeeper或redis实现分布式锁
前言 在分布式系统中,分布式锁是为了解决多实例之间的同步问题.例如master选举,能够获取分布式锁的就是master,获取失败的就是slave.又或者能够获取锁的实例能够完成特定的操作. 目前比较常 ...
随机推荐
- EPICS Archiver Appliance的定制部署2
EPICS Archiver Appliance的定制部署1 按上面的步骤Archiver可以跑起来了,试了一下,发现waveform不能archive,看服务状态: 看起来正常,怀疑在profile ...
- 手写一个audio播放器,实现歌曲切换,列表歌曲循环,音量调节等 vue组件
1 <template> 2 <div class="wrapper"> 3 <svg 4 t="1673833915638" 5 ...
- JZOJ 4308.长寿花
题面 思路 这种题当然要 \(dp\) 啦 设 \(g_{i,j}\) 表示前 \(i\) 个位置用指定的 \(j\) 种颜色装饰(即用颜色 \(1..j\) 来装饰) 那么 \(g_{i,j}=g_ ...
- JZOJ 4270.【NOIP2015模拟10.27】魔道研究
魔道研究 题面 思路 简单的想,就是在 \(T\) 个可重集合每个中选出 \(k\) 个最大的数组成新的可重集合,其中 \(k\) 为其编号 然后在新的集合中选前 \(n\) 大的数,求其和 考虑开 ...
- .net redis 发布订阅demo
发布者: using StackExchange.Redis;using System; namespace publish{ class Program { static void Main(str ...
- 第二周作业N67044-张铭扬
1. 运行脚本可以显示出本机的ip地址 2. 如果ip地址中有3这个数字,那么就打印出当前的系统时间 3. 如果ip地址中不含3这个数字,就批量建立用户magedu_00, magedu_01, .. ...
- 只会Jquery,后端程序员如何学会前端(webpack,react,babel,es5,es6)
写在前 希望通过短暂的学习,可以达到一下目标: 1.能看懂现在前端的工程化手段 2.知道当前前端群体中大致的解决问题的思路 3.当前的问题在哪里,技术发展趋势是什么 4.建立起自己的认知模型 文章内容 ...
- PXE自动安装linux系统
一.PXE自动安装Linux系统的大致流程 1.环境准备 2.安装所需的必要软件包并开启对应的服务 3.准备安装源 4.准备自动应答文件,并放到可以被访问到的地方 5.配置DHCP服务并启动 6.将必 ...
- 数值分析之数值积分 4.X
求积公式 \[\int_{a}^{b} f(x) \mathrm{d} x \approx \sum_{k=0}^{n} A_{k} f\left(x_{k}\right) \] \(A_k\) 为求 ...
- 预处理指令详解(C语言
一.预处理符号 预处理符号是C语言内置的符号,是可以直接使用的. 其中,若遵顼ANSI C,则__STDC__ 为1,否则未定义. 二.#define 1)定义标识符 define可以用来定义标识符, ...