zhangback
2025-11-18 3479ad5223c328be72a2b26ab66f9aeee64ec4b5
system/src/main/java/com/ruoyi/system/service/impl/SystemDataNoServiceImpl.java
@@ -4,6 +4,7 @@
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.enums.SystemDataNoEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysSerialNumber;
@@ -15,7 +16,9 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Slf4j
@@ -28,12 +31,15 @@
    @Autowired
    private RedisCache redisCache;
    /**流水号启用缓存*/
    @Value("${custom.serialNumber.cache.enabled:false}")
    private boolean serialNumberCache;
    @Autowired
    private ISysSerialNumberService serialNumberService;
    private static final long LOCK_WAIT_TIME = 5; // 尝试获取锁最大等待时间(秒)
    private static final long LOCK_LEASE_TIME = 10; // 锁的自动释放时间(秒)
    @Override
@@ -43,27 +49,43 @@
            return "";
        }
        String dayKey = DateUtils.dateYYMM();
        String dayKey = DateUtils.dateTime();
        String fullKey = baseNo + dayKey;
        RLock lock = redisLock.lock(Constants.SYS_DATASERIALNUMBER_KEYPREFIX + fullKey);
        RLock lock = redisLock.getRLock(Constants.SYS_DATASERIALNUMBER_KEYPREFIX + fullKey);
        boolean locked = false;
        try {
            if (!lock.tryLock(60, TimeUnit.SECONDS)) {
                throw new RuntimeException("获取锁失败");
            locked = lock.tryLock(LOCK_WAIT_TIME, LOCK_LEASE_TIME, TimeUnit.SECONDS);
            if (!locked) {
                throw new RuntimeException("获取锁失败,请稍后重试");
            }
            log.info("{}进入", Thread.currentThread().getName());
            Integer serial = getOrInitSerialNumber(fullKey, baseNo, dayKey);
            redisCache.setCacheObject(fullKey, serial, 1000, TimeUnit.DAYS);
            redisCache.setCacheObject(fullKey, serial, 1, TimeUnit.DAYS);
            return formatSerialNumber(fullKey, serial);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("获取锁异常", e);
        } finally {
            unlockIfHeld(lock);
            if (locked) {
                unlockIfHeld(lock);
            }
        }
    }
    private void unlockIfHeld(RLock lock) {
        try {
            if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        } catch (Exception e) {
            log.warn("释放锁异常: {}", e.getMessage(), e);
        }
    }
    // 以下方法保持原样
    private Integer getOrInitSerialNumber(String fullKey, String baseNo, String dayKey) {
        Integer serial = serialNumberCache ? redisCache.getCacheObject(fullKey) : null;
@@ -93,9 +115,5 @@
        return prefix + String.format("%04d", serial);
    }
    private void unlockIfHeld(RLock lock) {
        if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }
}