lua操作redis

参考: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";
        }
    }

}

作者:hasome

出处:https://www.cnblogs.com/hasome/p/17702037.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   hasome  阅读(55)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示