基于Redis实现分布式锁
分布式锁具有的特性:
1、排他性:
文件系统:
数据库:主键 唯一约束 for update
性能较差,容易出现单点故障
锁没有失效时间,容易死锁
缓存Redis:setnx
实现复杂:
存在死锁(或短时间死锁)的可能
zookeeper:类似文件系统
实现相对简单
可靠性高
性能较好
应用场景:
自动生成编码,格式为:"YYYYMMDD001"
多客户同时提交数据,数据库里出现多人存储一个编码。应实现效果,每人一个编码。
解决方案:
1、在redis里,创建一个编码池(每天凌晨1点初始化)。
2、每次项目启动,初始化redis编码池
3、编码池里没有编码,去数据库里查询当天最大编码,然后+1
@Component
public class CodeNumPool implements ApplicationRunner { @Autowired
private ICodeNumRedisService codeNumRedisService; @Autowired
private PeopleBusinessBasicInfoRepository peopleBusinessBasicInfoRepository; /**
* @Author: qsy
* @Date: Created in 上午 11:24 2019/1/3/003
* @Description: 每天1:00重置编码池
*/
@Scheduled(cron = "0 0 1 * * ?")
public void ResetCodeNoPool() {
codeNumRedisService.deleteCodeNumPool();
codeNumRedisService.initCodeNumPool(1);
} /**
* @Author: qsy
* @Date: Created in 下午 4:59 2019/1/3/003
* @Description: 项目一启动就初始化redis编码池
*/
@Override
public void run(ApplicationArguments args) throws Exception {
String oldCodeNo = peopleBusinessBasicInfoRepository.findNewCodeNo();
String codeNum = CodeNoUtils.getDateStr(oldCodeNo);
Integer no = StringUtil.stringToInteger(codeNum.substring(9, 13));
codeNumRedisService.deleteCodeNumPool();
codeNumRedisService.initCodeNumPool(no);
}
}
public interface ICodeNumRedisService {
/**初始化编码池*/
boolean initCodeNumPool(int no);
/**获取编码*/
String getCodeNum();
/**清空编码池*/
boolean deleteCodeNumPool();
}
@Service
public class CodeNumRedisServiceImpl implements ICodeNumRedisService {
@Autowired
private RedisTemplate<String, String> redisTemplate; /**
* @Author: qsy
* @Date: Created in 下午 3:01 2019/1/3/003
* @Description: 初始化编码池
*/
@Override
public boolean initCodeNumPool(int no) {
Boolean res = redisTemplate.opsForValue().setIfAbsent(Constans.INIT_NUM_LOCK, Constans.INIT_NUM_LOCK);
if (res) {
ListOperations<String, String> list = redisTemplate.opsForList();
for (int i = no; i < Constans.MAX_NUM; i++) {
String codeNo = StringUtil.DecimalFormat(i, Constans.FORMAT);
list.leftPush(Constans.CODE_NUM_POOL, "P" + DateUtil.getReqDate() + codeNo);
}
redisTemplate.delete(Constans.INIT_NUM_LOCK);
} return true;
} /**
* @Author: qsy
* @Date: Created in 下午 3:01 2019/1/3/003
* @Description: 获取编码
*/
@Override
public String getCodeNum() {
//加锁
while (true) {
Boolean res = redisTemplate.opsForValue().setIfAbsent(Constans.NUM_LOCK, Constans.INIT_NUM_LOCK);
if (res) {
ListOperations<String, String> list = redisTemplate.opsForList();
//释放锁
String num = list.rightPop(Constans.CODE_NUM_POOL);
redisTemplate.delete(Constans.NUM_LOCK);
return num;
}
}
} /**
* @Author: qsy
* @Date: Created in 下午 3:00 2019/1/3/003
* @Description: 清空编码池
*/
@Override
public boolean deleteCodeNumPool() {
return redisTemplate.delete(Constans.CODE_NUM_POOL);
}
}
基于Redis实现分布式锁的更多相关文章
- 基于redis 实现分布式锁的方案
在电商项目中,经常有秒杀这样的活动促销,在并发访问下,很容易出现上述问题.如果在库存操作上,加锁就可以避免库存卖超的问题.分布式锁使分布式系统之间同步访问共享资源的一种方式 基于redis实现分布式锁 ...
- 基于redis的分布式锁
<?php /** * 基于redis的分布式锁 * * 参考开源代码: * http://nleach.com/post/31299575840/redis-mutex-in-php * * ...
- 基于Redis的分布式锁真的安全吗?
说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...
- 基于 Redis 的分布式锁
前言 分布式锁在分布式应用中应用广泛,想要搞懂一个新事物首先得了解它的由来,这样才能更加的理解甚至可以举一反三. 首先谈到分布式锁自然也就联想到分布式应用. 在我们将应用拆分为分布式应用之前的单机系统 ...
- 基于redis的分布式锁(转)
基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...
- 基于redis的分布式锁实现
1.分布式锁介绍 在计算机系统中,锁作为一种控制并发的机制无处不在. 单机环境下,操作系统能够在进程或线程之间通过本地的锁来控制并发程序的行为.而在如今的大型复杂系统中,通常采用的是分布式架构提供服务 ...
- 基于redis的分布式锁(不适合用于生产环境)
基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...
- 基于 redis 的分布式锁实现 Distributed locks with Redis debug 排查错误
小结: 1. 锁的实现方式,按照应用的实现架构,可能会有以下几种类型: 如果处理程序是单进程多线程的,在 python下,就可以使用 threading 模块的 Lock 对象来限制对共享变量的同步访 ...
- 转载:基于Redis实现分布式锁
转载:基于Redis实现分布式锁 ,出处: http://blog.csdn.net/ugg/article/details/41894947 背景在很多互联网产品应用中,有些场景需要加锁处理,比如 ...
- redis系列:基于redis的分布式锁
一.介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分为两部分,一个是单机环境, ...
随机推荐
- 基于Twitter的Snowflake算法实现分布式高效有序ID生产黑科技(无懈可击)
参考美团文档:https://tech.meituan.com/2017/04/21/mt-leaf.html Twitter-Snowflake算法产生的背景相当简单,为了满足Twitter每秒上万 ...
- Asp.NetCore依赖注入和管道方式的异常处理及日志记录
前言 在业务系统,异常处理是所有开发人员必须面对的问题,在一定程度上,异常处理的能力反映出开发者对业务的驾驭水平:本章将着重介绍如何在 WebApi 程序中对异常进行捕获,然后利用 Nlog ...
- There was a problem with the instance info replicator
There was a problem with the instance info replicator 错误原因: 该服务尝试将自己作为客服端注册 解决办法: 在application.yml配置 ...
- int-Integer-String之间的转换方式
1.int和Integer之间的转换: 1) int----->Integer ①自动装箱 ②Integer的构造方法 ③调用Integer的静态方法:static Integer valu ...
- ubuntu server 16.04 开启root密码登录
0x00 ubuntu server 16.04 开启root密码登录 由于众多VPS默认使用证书验证登录,虽然安全但使用十分不便,所以特提供开启root用户并使用密码登录方法. 0x01 为root ...
- 生鲜配送管理系统_升鲜宝 V2.0 小程序辅助系统工具矩阵系列相关说明
随着微信红利的进一步释放,使用人群的不断增加,小程序从2017年01月第一批开发者出现后,2018年小程序得到快速的提升,小程序开发的相关应用小工具得到了市场的青咪,社会化大分工.协同.共享.协作的思 ...
- C# 利用位运算传递多个参数方法
前言 在工作中用sendMessage的方法向另外一个进程中传递窗体的位置,长度,宽度四个值,但是sendMessage的方法签名中只有两个参数.于是在网上找到了一些代码,找到了这个利用位运算来合并参 ...
- Android - 文字向上翻滚效果的实现
本文转载https://xwc2013.iteye.com/blog/1976051 今天看到了一种文字翻滚的效果,感觉非常实用.所以就自己试着做出了这种效果,现在把它分享给大家! 首先在res目录下 ...
- Java中字符串相加和字符串常量相加区别
有一道这样的程序: public class TestStringDemo { public static void main(String[] args) { String s1 = "P ...
- 局域网git服务器搭建(基于win7 + bonobo git server)
公司内网有一台win7系统的服务器. 准备在上面部署git后台, 用于内网项目版本管理. 搜索了相关资料后, 在根据公司环境, 决定采用win7 + bonobo git server + git的方 ...