首页 > 数据库 >lua操作redis

lua操作redis

时间:2023-09-14 11:25:46浏览次数:40  
标签:return uuid -- redis lua 操作 stringRedisTemplate

参考:https://blog.csdn.net/weixin_54721305/article/details/125648123

实现分布式锁

依赖

<dependencies>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter</artifactId>
          <version>2.2.1.RELEASE</version>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
          <version>2.2.1.RELEASE</version>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-redis</artifactId>
          <version>2.2.1.RELEASE</version>
      </dependency>
</dependencies>

application.properties

# 指定端口号
server.port=8199

# 连接redis
spring.redis.host=192.168.171.138
spring.redis.port=6379

config

/**
 * @Author 嘉宾
 * @Data 2022/7/6 20:37
 * @Version 1.0
 * @Description 用于声明lua
 */
@Configuration
public class LuaRedisConfig {

    /**
     * 分布式锁脚本
     * @return
     */
    @Bean
    public DefaultRedisScript<Long> lockRedisScript() {
        // 定义DefaultRedisScript
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
        // 指定lua脚本路径
        redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/lock.lua")));
        // 设置返回类型
        redisScript.setResultType(Long.class);
        return redisScript;     // 返回lua脚本内容
    }
    
}

script

在resources目录下创建目录script目录在其目录下创建Lua脚本文件

local lockUUID = KEYS[1]    -- 锁中的uuid值
local uuid = ARGV[1]        -- 用户的uuid值

-- 判断锁中的uuid是否与用户的uuid相等
if redis.call('get',lockUUID) == uuid then
    return redis.call('del',lockUUID)   -- 相等的话就释放锁
else    -- 未获得锁
    return 0    -- 返回0
end

controller

/**
 * @Author 嘉宾
 * @Data 2022/7/6 20:39
 * @Version 1.0
 * @Description
 */
@RestController
@RequestMapping("/lua")
public class TestController {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private DefaultRedisScript<Boolean> lockRedisScript;    // 分布式锁脚本

    /**
     * 计数
     * @return
     */
    @GetMapping("/getLock")
    public String getLock(){
        // 生成UUID
        String uuid = UUID.randomUUID().toString();
        // 1、获取锁:true得到锁,false未得到
        Boolean redisLock = stringRedisTemplate.opsForValue().setIfAbsent("lock_redis", uuid,3, TimeUnit.SECONDS);
        // 判断是否得到锁
        if(redisLock){
            // ...自己的业务
            String value = stringRedisTemplate.opsForValue().get("num");
            if(StringUtils.isEmpty(value)){
                stringRedisTemplate.opsForValue().set("num","1");
            }
            int num = Integer.parseInt(value + "") + 1;
            stringRedisTemplate.opsForValue().set("num",num+"");
            // 获取锁中的内容
            String lockUUID = stringRedisTemplate.opsForValue().get("lock_redis");
            // 使用Lua脚本比较
            // 指定参数
            List<String> keys = Arrays.asList(lockUUID);
            stringRedisTemplate.execute(lockRedisScript,keys,uuid);
            return "success"+num;
        }else{
//            // 每隔0.1秒再获取一次
//            try {
//                Thread.sleep(100);
//                this.getLock();
//            }catch (InterruptedException e){
//                e.printStackTrace();
//            }
            return "miss";
        }
    }

}

标签:return,uuid,--,redis,lua,操作,stringRedisTemplate
From: https://www.cnblogs.com/hasome/p/17702037.html

相关文章

  • 关于 Angular 应用里 Rxjs filter 操作符内的双重感叹号的用法
    看下列这段出现在AngularComponent内的代码:protecteduserCostCenters$:Observable<CostCenter[]>=this.userCostCenterService.getActiveCostCenters().pipe(filter((costCenters)=>!!costCenters));这段Angular组件代码涉及到Observable和RxJS操作......
  • 关于 windows 操作系统任务管理器里的 mcshield.exe
    mcshield.exe是McAfee防病毒软件的一个重要组成部分,用于实时扫描和监控计算机上的文件和进程,以确保系统的安全性。在本文中,我将详细介绍mcshield.exe的功能、工作原理以及如何管理它。mcshield.exe概述mcshield.exe是McAfee防病毒软件中的一个主要执行文件,通常位于C:......
  • combineLatest 操作符在 Spartacus Cost Center 计算逻辑中的一个实际应用
    考虑下面这段Angular代码:this.costCenters$=combineLatest([this.userCostCenters$,this.checkoutCostCenterFacade.getCostCenterState().pipe(filter((state)=>!state.loading),map((state)=>state.data),distinctUntilCh......
  • 达人探店业务之点赞、排行榜功能(Redis经典场景)
    达人探店业务之点赞、排行榜功能(Redis经典场景)初始代码:@GetMapping("/likes/{id}")publicResultqueryBlogLikes(@PathVariable("id")Longid){//修改点赞数量blogService.update().setSql("liked=liked+1").eq("id",id).update();ret......
  • 学习笔记之Redis消息队列-基于Stream的消息队列
    学习笔记之Redis消息队列-基于Stream的消息队列Stream是Redis5.0引入的一种新数据类型,可以实现一个功能非常完善的消息队列。其实只需要知道写入消息队列的命令和读取消息队列的命令就行了写入消息队列:XADD读取消息队列的方式之一:XREAD在业务开发中,我们可以循环的调用......
  • conda中新建虚拟环境等相关操作
    1基础命令1-新建虚拟环境:condacreate-nyou_env_namepython=3.72-查看当前有哪些虚拟环境:condaenvlist3-激活某个虚拟环境:conda.batactivateyour_env_name4-在虚拟环境中安装包和依赖:condainstallxxx5-删除虚拟环境:condaremove-nxxxx--all......
  • Java有关队列的基本操作
    什么是队列?队列是一种线性数据结构,队列中的元素只能先进先出;队列的出口端叫做队头,入口端叫做队尾。队列的基本操作1.入队:只允许在队尾的位置放入元素,新元素的下一个位置将会成为新的队尾;publicvoidenQueue(intelement)throwsException{if((rea......
  • Redis7 10大数据类型(Redis列表)
    一、常用二、单key多value三、简单说明一个双端链表的结构,容量是2的32次方减1个元素,大概40多亿,主要功能有push/pop等,一般用在栈、队列、消息队列等场景。left、right都可以插入添加;如果键不存在,创建新的链表;如果键已存在,新增内容;如果值全移除,对应的键也就消失了。它的底层实......
  • ubuntu redis安装
    1.1更新仓库sudoaptupdate1.2使用apt从官方Ubuntu存储库来安装Redissudoapt-getinstallredis-server二、设置密码2.1打开Redis配置文件redis.confsudovi/etc/redis/redis.conf2.2找到#requirepassfoobared这一行,将注释符号#去掉,将后面修改成自己的密......
  • 文件操作和io
    文件的概念文件分为狭义的文件和广义的文件,这里讨论的是狭义的文件。文件是针对硬盘抽象出来的概念,当我们想要将数据保存再硬盘上时,是以文件的形式来保存的,并且是以文件为单位来保存的。文件包含的信息有文件名,文件类型,文件大小等,我们把这些信息视为文件的原信息。由于文件的繁......