|
@@ -389,7 +389,14 @@ public class IotOpeationFillServiceImpl implements IotOpeationFillService {
|
|
|
// 日期格式化器,用于生成每天的唯一标识
|
|
|
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
|
|
|
|
|
|
- public static synchronized int generateUniqueNumber() {
|
|
|
+ /**
|
|
|
+ * 生成每天唯一的6位数字序列号
|
|
|
+ * 格式:两位日期码 + 四位序列号
|
|
|
+ *
|
|
|
+ * @return 唯一的6位数字
|
|
|
+ * @throws RuntimeException 当超过每日最大生成量时抛出
|
|
|
+ */
|
|
|
+ public static int generateUniqueNumber() {
|
|
|
// 获取当前日期字符串,如20231005
|
|
|
String today = LocalDate.now().format(DATE_FORMATTER);
|
|
|
|
|
@@ -398,18 +405,30 @@ public class IotOpeationFillServiceImpl implements IotOpeationFillService {
|
|
|
Integer.parseInt(today.substring(4, 6)) +
|
|
|
Integer.parseInt(today.substring(6, 8))) % 99 + 1;
|
|
|
|
|
|
- // 获取并递增当天的序列号,不存在则初始化为1
|
|
|
- int seq = dailySequence.merge(today, 1, Integer::sum);
|
|
|
+ // 使用循环确保获取到正确的序列号,处理并发情况
|
|
|
+ while (true) {
|
|
|
+ // 获取当前序列号,不存在则为0
|
|
|
+ Integer current = dailySequence.get(today);
|
|
|
+ int nextSeq = (current == null) ? 1 : current + 1;
|
|
|
|
|
|
- // 检查是否超过每天的最大生成量
|
|
|
- if (seq > 9999) {
|
|
|
- // 回退计数器,因为我们已经递增了它
|
|
|
- dailySequence.put(today, 9999);
|
|
|
- throw new RuntimeException("今日已超过最大生成数量(9999个)");
|
|
|
- }
|
|
|
+ // 检查是否超过每天的最大生成量
|
|
|
+ if (nextSeq > 9999) {
|
|
|
+ throw new RuntimeException("今日已超过最大生成数量(9999个)");
|
|
|
+ }
|
|
|
|
|
|
- // 组合日期标识和序列号,生成6位唯一数字
|
|
|
- return dateCode * 10000 + seq;
|
|
|
+ // 使用putIfAbsent确保原子性操作,如果不存在则设置为1
|
|
|
+ if (current == null) {
|
|
|
+ if (dailySequence.putIfAbsent(today, 1) == null) {
|
|
|
+ return dateCode * 10000 + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 使用replace确保只有当前值匹配时才更新,避免覆盖其他线程的更新
|
|
|
+ else if (dailySequence.replace(today, current, nextSeq)) {
|
|
|
+ return dateCode * 10000 + nextSeq;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果上述操作失败,循环重试
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|