随笔 - 441  文章 - 4  评论 - 84  阅读 - 109万 

在实际的业务场景中,我们会用到流水号。
之前的流水号做法是,使用redis的全局锁。然后对数据库进行更新,数据库更新 这个也会有一些问题,比如对于同一个流水号,多个线程去更新,由于事务比较长,那么就会导致数据库被锁定。

这个可以使用redis的lua 脚本去解决。

由于redis 是单线程的处理模式,因此执行 lua 脚本的时候,是不会有并发问题的。

相关代码:

private Long getNo(String key,Integer initVal,Short step,Integer timeout){
        DefaultRedisScript<Long> redisScript= new DefaultRedisScript<>();

        //setex (key,timeout,val)
        String script="if(redis.call('exists',KEYS[1])==0) then  redis.call('setex',KEYS[1], tonumber(KEYS[4]), tonumber(KEYS[2]))  else redis.call('incrby',KEYS[1],tonumber(KEYS[3])) end  return tonumber(redis.call('get',KEYS[1]))";

        redisScript.setScriptText(script);

        List list=new ArrayList<>();
        //键
        list.add(key);
        //初始值
        list.add(initVal.toString());
        //步长
        list.add(step.toString());
        //超时时间
        list.add(timeout.toString());

        redisScript.setResultType(Long.class);

        Long rtn=(Long) redisTemplate.execute(redisScript,list);

        return rtn;
    }

这里需要注意的是,KEYS 为参数,list为参数传入,这里需要保证数据的类型和redis 的函数保持一致。

另外我们需要保证redis 的存储。

我们可以使用AOF模式

//启动AOf
appendonly yes
//每秒同步
appendfsync everysec
posted on   自由港  阅读(322)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
历史上的今天:
2019-04-30 IDEA 基本操作
点击右上角即可分享
微信分享提示