You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何生成按日重置的顺序唯一Application Number并解决并发冲突

业务申请唯一序列号生成及并发冲突解决方案

核心规则适配

适配要求生成的编号格式为APP-日期-4位序列号,满足当日序列号持续递增、次日自动从0001重新计数的需求,同时彻底解决并发重复问题。

主流实现方案

1 关系型数据库实现(适用90%以上常规业务场景)

依赖数据库的事务和行锁机制保证原子性,实现成本低、数据一致性高:

  • 第一步:创建专用序列号生成表,示例建表语句如下:
CREATE TABLE `application_seq` (
  `date_key` varchar(8) NOT NULL COMMENT '日期主键,格式为yyyyMMdd',
  `current_seq` int NOT NULL DEFAULT '0' COMMENT '当前已分配的最大序列号',
  PRIMARY KEY (`date_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  • 第二步:每次生成编号时开启事务,执行SELECT current_seq FROM application_seq WHERE date_key = '当前日期字符串' FOR UPDATE给当日行加排他锁,若查询无结果则插入当日初始记录,current_seq默认值为0
  • 第三步:执行UPDATE application_seq SET current_seq = current_seq + 1 WHERE date_key = '当前日期字符串',拿到更新后的序列号
  • 第四步:将序列号补前导0至4位,按APP-YYYYMMDD-xxxx格式拼接得到最终申请号,提交事务即可
  • 兜底配置:给业务表的application_number字段添加唯一索引,极端场景下也会拒绝重复数据落库

2 Redis实现(适用高并发分布式场景)

依赖Redis原生原子操作实现,性能远高于数据库方案,适合qps较高的业务:

  • 以日期为key存储当日序列号,key命名规则示例:app_seq:20240520
  • 每次生成编号时直接执行INCR app_seq:当前日期命令,该操作是原子性的,天然规避并发冲突,返回值即为本次可用的序列号
  • 给每个日期key设置48小时过期时间,次日新请求会自动生成新的key从1开始计数,过期的历史key自动清理
  • 同数据库方案,需要在业务表侧给申请号加唯一索引作为兜底,避免Redis故障、数据丢失时出现重复编号

并发冲突规避核心要点

并发重复的根因是多个请求同时读取到同一个序列号,并行执行加1操作导致生成相同编号,规避时需注意以下几点:

  • 禁止单独使用服务内存存储序列号,集群部署时内存不共享必然会出现重复
  • 锁粒度仅控制在单日维度,不要锁全表,避免影响序列号生成性能
  • 所有序列号更新操作必须是原子性的,禁止用先查再改的非原子逻辑
  • 若业务允许少量跳号,优先选择无回收逻辑的方案,性能更高;若严格要求连续不跳号,可增加失效序列号回收池,分配时优先取回收池内的序列号

内容的提问来源于stack exchange,提问作者user3913335

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 09:48:04