当前位置: 首页 > news >正文

使用 Redis + Redisson 分布式锁来生成全局唯一、线程安全的带日期前缀的流水号的完整实现。

业务需求:创建一个流水号,

功能说明:

1,格式:orgCode + yyyyMMdd + 4位序号,
2,每天重新从 0001 开始
3,使用 Redisson 保证并发下分布式唯一,
4,Redis 存储当天序列号

示例代码

  1. Maven 依赖(如果还没加 Redisson):
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.17.7</version>
</dependency>

  1. 配置 RedissonClient(示例单节点):
@Configuration
public class RedissonConfig {
    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer()
              .setAddress("redis://127.0.0.1:6379") // 修改为你自己的 Redis 地址
              .setDatabase(0);
        return Redisson.create(config);
    }
}

  1. 流水号工具类:
@Component
public class SerialNumberGenerator {

    @Autowired
    private RedissonClient redissonClient;

    private static final String SERIAL_KEY_PREFIX = "serial:";

    public String generateSerialNumber(String orgCode) {
        String currentDate = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String key = SERIAL_KEY_PREFIX + currentDate;

        String lockKey = "lock:serial:" + currentDate;
        RLock lock = redissonClient.getLock(lockKey);

        try {
            // 获取锁,最多等待5秒,锁自动释放时间为10秒
            if (lock.tryLock(5, 10, TimeUnit.SECONDS)) {
                RAtomicLong counter = redissonClient.getAtomicLong(key);

                // 如果是新的一天,重置为0
                if (!counter.isExists()) {
                    counter.set(0);
                    // 设置过期时间为2天,避免key一直存在
                    counter.expire(2, TimeUnit.DAYS);
                }

                long serial = counter.incrementAndGet();
                String formattedSerial = String.format("%04d", serial);
                return orgCode + currentDate + formattedSerial;
            } else {
                throw new RuntimeException("生成流水号失败:获取锁超时");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException("生成流水号失败:线程中断", e);
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}

为什么需要 Redis 分布式锁?
不加锁的问题
Redis 是高并发环境下的共享存储,多个实例并发 get + set 操作有可能导致并发写丢失或重复编号。
加锁保证:每次生成编号时只有一个线程在操作该 key 的值,从而保证原子性和唯一性
在这里插入图片描述

相关文章:

  • 【FPGA开发技巧】Modelsim仿真中,显示状态机的名称,而非编码数字
  • 水库大坝安全监测系统
  • 蓝桥杯--结束
  • 缓存不只是加速器:深入理解 Redis 的底层机制
  • Unity IL2CPP内存泄漏追踪方案(基于Memory Profiler)技术详解
  • Charles的安装和使用教程
  • 高支模自动化监测解决方案
  • MACOS15版本安装 python mysqlclient 以连接mysql 8.0
  • 小推桌面-一款全新的第三方电视桌面-全网通桌面
  • Python数据可视化-第8章-使用matplotlib绘制高级图表
  • 后端面试问题收集以及答案精简版
  • MySQL 事务的优先级
  • [ctfshow web入门] web41
  • 物理备份工具 BRM vs gs_probackup
  • AndroidTV D贝桌面-v3.2.5-[支持文件传输]
  • “破解”GPT-4o生图技术:万物皆可吉卜力的技术路线推测
  • w285药店管理系统的设计与实现
  • 腾讯OCR文字识别实践--简历文本识别
  • Redis简介及其在Unity中的应用
  • Azure AI Foundry 正在构建一个技术无障碍的未来世界
  • 私密浏览器免费版的优缺点/seo薪酬如何
  • 餐饮网站制作/网页seo是什么意思
  • 中小微企业查询官网/温州seo外包公司
  • 如何使用c 进行网站开发/传统营销与网络营销的区别
  • 做网站点击量有用吗/泰州seo外包公司
  • 建网站用html/哪有培训seo