Эх сурвалжийг харах

运行记录1011-确保生成日报设备的device_id当天唯一性

yuanchao 4 өдөр өмнө
parent
commit
0a95b9ac01

+ 30 - 11
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotopeationfill/IotOpeationFillServiceImpl.java

@@ -389,7 +389,14 @@ public class IotOpeationFillServiceImpl implements IotOpeationFillService {
     // 日期格式化器,用于生成每天的唯一标识
     // 日期格式化器,用于生成每天的唯一标识
     private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
     private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
 
 
-    public static synchronized int generateUniqueNumber() {
+    /**
+     * 生成每天唯一的6位数字序列号
+     * 格式:两位日期码 + 四位序列号
+     *
+     * @return 唯一的6位数字
+     * @throws RuntimeException 当超过每日最大生成量时抛出
+     */
+    public static int generateUniqueNumber() {
         // 获取当前日期字符串,如20231005
         // 获取当前日期字符串,如20231005
         String today = LocalDate.now().format(DATE_FORMATTER);
         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(4, 6)) +
                 Integer.parseInt(today.substring(6, 8))) % 99 + 1;
                 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;
+            }
+
+            // 如果上述操作失败,循环重试
+        }
     }
     }