返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Redis对批量数据实现分布式锁的实现代码
  • 522
分享到

Redis对批量数据实现分布式锁的实现代码

2024-04-02 19:04:59 522人浏览 八月长安
摘要

目录需求背景代码实现实现效果需求背景 在开发的收入结转平台界面上有一个归集按钮,可以实现抓取结转表里面的多条数据进行归集操作。为了防止多人多电脑同时操作一条数据,我们自己开发了一个简

需求背景

开发收入结转平台界面上有一个归集按钮,可以实现抓取结转表里面的多条数据进行归集操作。为了防止多人多电脑同时操作一条数据,我们自己开发了一个简单的基于Redis实现的分布式

代码实现

逻辑代码中的使用案例

参数说明:

scIds:结转数据的ID主键集合

timeOutToDeleteRedisKey:最大锁超时时间(用于自动解锁)

organizationId:租户ID(这个参数根据情况选择是否需要)

ReturnLock returnLock = RedisLock.applyByIds(scIds, redisLockTime, organizationId, () -> {
    // dothing 具体的代码业务逻辑
    return 123;
});
 
if (!returnLock.getFlag()) {
    if(returnLock.getLock()){
        throw new CommonException("归集数据有程序正在运行,请稍候刷新页面重试");
    }else {
        throw new CommonException(returnLock.getErrORMsg());
    }
}
// 返回对象
System.out.println(returnLock.getResObj()) // 123

Redis加锁方法封装

public static ReturnLock applyByIds(List<Long> scIds, Long timeOutToDeleteRedisKey, Long tenantId,
                                    Supplier<Object> supplier) {
    // 获得锁
    Map<String, String> keyMap = getLockByIds(scIds, timeOutToDeleteRedisKey, tenantId);
    ReturnLock returnLock = new ReturnLock();
    returnLock.setFlag(true);
    returnLock.setLock(false);
    try {
        // 判断主键ID数量和加锁的数量是否一致,不一致说明有加锁失败的数据,返回失败锁信息
        if(scIds.size() > keyMap.size()){
            returnLock.setFlag(false);
            returnLock.setLock(true);
            returnLock.seTKEyMap(keyMap);
            return returnLock;
        }
        // 应用代码执行后的返回结果 supplier:java8四大内置函数的供给型接口
        // Supplier<T>(供给型接口)无参数,返回类型为T的对象:T get()
        returnLock.setResObj(supplier.get());
    }catch (Exception e) {
        returnLock.setFlag(false);
        returnLock.setErrorMsg(e.getMessage());
        e.printStackTrace();
    }finally {
        // 应用代码执行报错,解锁
        unLockByIds(keyMap);
    }
    return returnLock;
}

getLockByIds

批量获取每一条数据的Redis锁

private static Map<String, String> getLockByIds(List<Long> scIds, Long timeOutToDeleteRedisKey, Long tenantId) {
    Map<String, String> keyMap = new HashMap<>();
    // 从spring上下文中获取Redis的操作对象,因为这个代码是写在util中,所以通过上下文方式获取bean对象
    // RedisHelper:Redis的操作对象,我们自己公司基于redisTemplate封装的
    RedisHelper redisHelper = SpringUtil.getBean(RedisHelper.class);
    try {
        if (CollectionUtil.isNotEmpty(scIds)) {
            for (int i = 0; i < scIds.size(); i++) {
                String item = "L_" + scIds.get(i);
                String UUID = UUIDUtils.generateTenantUUID(tenantId);
                // 判断key值是否被锁,如果没有锁则加锁并设置过期时间, 如果有锁, 则报错并立即释放已加的锁
                // strSetIfAbsent会返回true/false,底层是封装了java的setIfAbsent方法和Redis的setnx方法
                // 如果设置成功返回true否则false
                if (redisHelper.strSetIfAbsent(item, UUID)) {
                    // 设置过期时间
                    redisHelper.setExpire(item, timeOutToDeleteRedisKey, TimeUnit.SECONDS);
                    // 保存设置的锁信息
                    keyMap.put(item, UUID);
                } else {
                    // 锁设置异常,表示有数据被锁住了,解锁之间加锁的数据
                    if (MapUtil.isNotEmpty(keyMap)) {
                        if (unLockByIds(keyMap)) {
                            // 解锁失败再次解锁
                            unLockByIds(keyMap);
                        }
                    }
                    // 返回锁信息
                    return keyMap;
                }
            }
        }
        return keyMap;
    }catch (Exception e) {
        e.printStackTrace();
    }
}

解锁

private static Boolean unLockByIds(Map<String, String> keyMap) {
    RedisHelper redisHelper = SpringUtil.getBean(RedisHelper.class);
    try {
        if (MapUtil.isEmpty(keyMap)) {
            return false;
        }
        // 判断是否是自己的锁
        for (String key : keyMap.keySet()) {
            String uuid = keyMap.get(key);
            if (StringUtils.equals(uuid, redisHelper.strGet(key))) {
                // 封装了redisTemplate.delete(key);
                redisHelper.delkey(key);
            }
        return true;
    }catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

实现效果

当对数据进行批量加锁的时候,若在加锁的过程中出现加锁失败,则回滚直接加的锁,并提示"归集数据有程序正在运行,请稍候刷新页面重试"。

若业务代码逻辑执行成功或者执行报错都会自动的解锁当前加锁的数据。

到此这篇关于利用Redis对批量数据实现分布式锁的文章就介绍到这了,更多相关Redis分布式锁内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Redis对批量数据实现分布式锁的实现代码

本文链接: https://lsjlt.com/news/143692.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Redis对批量数据实现分布式锁的实现代码
    目录需求背景代码实现实现效果需求背景 在开发的收入结转平台界面上有一个归集按钮,可以实现抓取结转表里面的多条数据进行归集操作。为了防止多人多电脑同时操作一条数据,我们自己开发了一个简...
    99+
    2024-04-02
  • 基于Redis分布式锁的实现代码
    概述 目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题。分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(...
    99+
    2024-04-02
  • redis分布式锁之可重入锁的实现代码
    上篇redis实现的分布式锁,有一个问题,它不可重入。 所谓不可重入锁,即若当前线程执行某个方法已经获取了该锁,那么在方法中尝试再次获取锁时,就会获取不到被阻塞。 同一个人拿一个锁 ...
    99+
    2024-04-02
  • Redis——》实现分布式锁
    推荐链接:     总结——》【Java】     总结——》【Mysql】     总结——》【Redis】     总结——》【Kafka】     总结——》【Spring】     总结—...
    99+
    2023-09-03
    redis 分布式 过期 lua
  • Redis实现分布式锁
    单体锁存在的问题 在单体应用中,如果我们对共享数据不进行加锁操作,多线程操作共享数据时会出现数据一致性问题。 (下述实例是一个简单的下单问题:从redis中获取库存,检查库存是否够,>0才允许下单) 我们的解决办法通常是加锁。如下加单体锁...
    99+
    2023-08-16
    分布式 java jvm
  • redis分布式锁的实现
    一、使用分布式锁要满足的几个条件:1、系统是一个分布式系统(关键是分布式,单机的可以使用ReentrantLock或者synchronized代码块来实现)2、共享资源(各个系统访问同一个资源,资源的载体可...
    99+
    2024-04-02
  • 用Go+Redis实现分布式锁的示例代码
    目录为什么需要分布式锁 分布式锁需要具备特性 实现 Redis 锁应先掌握哪些知识点 set 命令 Redis.lua 脚本 go-zero 分布式锁 RedisLock 源码分析 ...
    99+
    2024-04-02
  • 用Go+Redis实现分布式锁的示例代码
    目录为什么需要分布式锁分布式锁需要具备特性实现 Redis 锁应先掌握哪些知识点set 命令Redis.lua 脚本go-zero 分布式锁 RedisLock 源码分析关于分...
    99+
    2022-06-07
    GO 示例 分布式 分布 分布式锁 Redis
  • Redis Template实现分布式锁
    今天就跟大家聊聊有关Redis Template实现分布式锁,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。可靠性首先,为了确保分布式锁可用,我们至少...
    99+
    2024-04-02
  • PHP+Redis实现分布式锁
    目录 一、分布式锁概述 二、redis实现锁的命令 1、redis实现锁的命令 3、释放锁的步骤 三、PHP+redis分布式锁示例 四、redis集群分布式锁 一、分布式锁概述         在分布式环境下,各个线程通过对公共资...
    99+
    2023-09-15
    分布式锁
  • Redis实现分布式锁(SETNX)
    目录 1、什么是分布式锁 2、分布式锁应具备的条件         3、为什么使用分布式锁 4、SETNX介绍 5、分布式锁实现 6、效果演示 7、Redisson分布式锁详解 8、Lua脚本实现可重入分布式锁 1、什么是分布式锁  ...
    99+
    2023-10-21
    redis 分布式 java spring boot 后端
  • python实现redis分布式锁
    #!/usr/bin/env python # coding=utf-8 import time import redis class RedisLock(object): def __init__(self, key): ...
    99+
    2023-01-31
    分布式 python redis
  • C#实现Redis的分布式锁
    目录Redis实现分布式锁(悲观锁/乐观锁)Redis连接池使用Redis的SetNX命令实现加锁,调用方式Redis实现分布式锁(悲观锁/乐观锁) 对锁的概念和应用场景在此就不阐...
    99+
    2024-04-02
  • Redis分布式锁Redlock的实现
    目录普通实现Redlock实现Redlock源码用法唯一ID获取锁释放锁普通实现 说道Redis分布式锁大部分人都会想到:setnx+lua,或者知道set key value p...
    99+
    2024-04-02
  • Redis分布式锁的实现方式
    目录一、分布式锁是什么1、获取锁2、释放锁二、代码实例上面代码存在锁误删问题:三、基于SETNX实现的分布式锁存在下面几个问题1、不可重入2、不可重试3、超时释放4、主从一致性四、Redisson实现分布式锁1、pom2...
    99+
    2023-04-03
    Java Redis分布式锁实现方式 实现Redis分布式锁 Redis分布式锁实现
  • Redis分布式锁之红锁的实现
    目录一、问题二、办法三、原理四、实战一、问题 分布式锁,当我们请求一个分布式锁的时候,成功了,但是这时候slave还没有复制我们的锁,masterDown了,我们的应用继续请求锁的时候,会从继任了master的原slav...
    99+
    2022-08-09
    Redis红锁
  • Redis数据库中实现分布式锁的方法
    分布式锁是一个在很多环境中非常有用的原语,它是不同进程互斥操作共享资源的唯一方法。有很多的开发库和博客描述如何使用Redis实现DLM(Distributed Lock Manager),但是每个开发库使用...
    99+
    2022-06-04
    分布式 数据库中 方法
  • redis实现分布式锁实例分析
    本文小编为大家详细介绍“redis实现分布式锁实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“redis实现分布式锁实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1、业务场景引入模拟一个电商系统,...
    99+
    2023-06-29
  • java基于jedisLock—redis分布式锁实现示例代码
    分布式锁是啥?单机锁的概念:我们正常跑的单机项目(也就是在tomcat下跑一个项目不配置集群)想要在高并发的时候加锁很容易就可以搞定,java提供了很多的机制例如:synchronized、volatile、ReentrantLock等锁的...
    99+
    2023-05-30
    jedislock redis 分布式锁
  • 基于Redis实现分布式锁
    我们知道分布式锁的特性是排他、避免死锁、高可用。分布式锁的实现可以通过数据库的乐观锁(通过版本号)或者悲观锁(通过for update)、Redis的setnx()命令、Zookeeper(在某个持久节点添加临时有序节点,判断当前节点是否是...
    99+
    2017-09-11
    基于Redis实现分布式锁
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作