zwhui 1 年之前
父節點
當前提交
917e455618

+ 21 - 0
midjourney/src/main/java/com/yhlxj/redis/RedisService.java

@@ -5,6 +5,7 @@ import lombok.AllArgsConstructor;
 import lombok.Getter;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
 import org.springframework.data.redis.core.ZSetOperations;
 import org.springframework.stereotype.Service;
 
@@ -747,6 +748,26 @@ public class RedisService {
         return StringUtil.getString(redisTemplate.opsForValue().getAndSet(key,s));
     }
 
+    /**
+     * 尝试加锁
+     * @param lockKey 锁的键
+     * @param expireTime 锁的过期时间(秒)
+     * @return 是否成功获取锁
+     */
+    public boolean tryLock(String lockKey, long expireTime) {
+        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
+        Boolean success = ops.setIfAbsent(lockKey, "LOCKED", expireTime, TimeUnit.SECONDS);
+        return success != null && success;
+    }
+
+    /**
+     * 释放锁
+     * @param lockKey 锁的键
+     */
+    public void unlock(String lockKey) {
+        redisTemplate.delete(lockKey);
+    }
+
     @AllArgsConstructor
     @Getter
     public enum key {

+ 24 - 13
midjourney/src/main/java/com/yhlxj/service/midjourney/impl/MidjourneyServiceImpl.java

@@ -16,9 +16,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
-import com.cyksj.common.util.Jsons;
-import com.cyksj.common.util.QueryWrapperUtils;
-import com.cyksj.common.util.StringUtil;
+import com.cyksj.common.util.*;
 import com.yhlxj.dao.mapper.GroupsRelationMapper;
 import com.yhlxj.dao.mapper.midjourney.*;
 import com.yhlxj.dao.model.dto.*;
@@ -52,6 +50,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
@@ -752,7 +751,6 @@ public class MidjourneyServiceImpl implements MidjourneyService {
 
     public void sync(MidjourneyUserConversation conversation) throws IOException {
         if ((StringUtils.isNotBlank(conversation.getProgress()) && progress.contains(conversation.getProgress())) || status.contains(conversation.getStatus())) {
-            synchronized (this) {
                 log.info("同步任务:{},进度:{}",conversation.getTaskId(),conversation.getProgress());
                 Long userId = conversation.getUserId();
                 MidjourneyUserConversation dbConversation = conversationMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUserConversation.class).eq(MidjourneyUserConversation::getTaskId, conversation.getTaskId())
@@ -785,21 +783,34 @@ public class MidjourneyServiceImpl implements MidjourneyService {
                         Object num = redisService.get(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + userId);
                         LambdaUpdateWrapper<MidjourneyUser> wrapper = Wrappers.lambdaUpdate(MidjourneyUser.class)
                                 .eq(MidjourneyUser::getId, userId);
-                        if (mode == 1){
-                            num =  redisService.incr(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + userId, 1L);
-                            wrapper.set(MidjourneyUser::getMjFastNum, num);
-                            midjourneyUserMapper.update(null, wrapper);
+
+                        // 使用Redis分布式锁避免重复扣除次数
+                        String lockKey = "sync:lock:" + conversation.getTaskId() + ":" + userId;
+                        // 尝试加锁
+                        boolean isLocked = redisService.tryLock(lockKey, 5);
+                        if (!isLocked) {
+                            // 未获取锁,避免重复操作
+                            return;
                         }
-                        if (mode == 2){
-                            if (num != null) {
-                                num = redisService.incr(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + userId, 1L);
-                                wrapper.set(MidjourneyUser::getMjRelaxNum, num);
+                        try {
+                            if (mode == 1){
+                                num =  redisService.incr(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + userId, 1L);
+                                wrapper.set(MidjourneyUser::getMjFastNum, num);
                                 midjourneyUserMapper.update(null, wrapper);
                             }
+                            if (mode == 2){
+                                if (num != null) {
+                                    num = redisService.incr(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + userId, 1L);
+                                    wrapper.set(MidjourneyUser::getMjRelaxNum, num);
+                                    midjourneyUserMapper.update(null, wrapper);
+                                }
+                            }
+                        } finally {
+                            // 释放锁
+                            redisService.unlock(lockKey);
                         }
                     }
                 }
-            }
         }
     }