浏览代码

订单分布式锁修改

weifanli 3 年之前
父节点
当前提交
fb8b4fcd80

+ 5 - 5
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserAccountServiceImpl.java

@@ -61,12 +61,12 @@ public class UserAccountServiceImpl extends ServiceImpl<UserAccountDao, UserAcco
             throw new BizException("缺少参数");
         }
 
-        Future<HttpResponseResult<UserAccountRecord>> httpResponseResultFuture = DistributedLock.of(redissonClient)
-                .callIfLockCanGet(CacheNameEnum.LOCK_CHANGE_ACCOUNT.getRedisKey(accountRecordDto.getUserId())
-                        , () -> doAccountChange(accountRecordDto), 60L, TimeUnit.SECONDS);
-
         try {
-            return httpResponseResultFuture.get();
+            return DistributedLock.of(redissonClient)
+                    .runIfLockCanGet(CacheNameEnum.LOCK_CHANGE_ACCOUNT.getRedisKey(accountRecordDto.getUserId())
+                            , () -> doAccountChange(accountRecordDto), 60L, TimeUnit.SECONDS);
+        } catch (BizException e) {
+            return HttpResponseResult.failed(e.getMessage());
         } catch (Exception e) {
             e.printStackTrace();
             throw new BizException("账户变更失败");

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java

@@ -250,6 +250,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
     @Override
     @Transactional(rollbackFor = Exception.class)
     public HttpResponseResult<UserOrder> executeOrder(OrderReq orderReq) throws Exception {
+        long start = System.currentTimeMillis();
         log.info("订单[创建订单] Req:{}", JSONObject.toJSONString(orderReq));
         //订单号生成
         Long orderNo = idGeneratorService.generatorId("userOrder");
@@ -291,6 +292,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
                 afterFunction.accept(orderDetailVo);
             }
         }
+        log.info("下单请求 start is {} end is {}", start, System.currentTimeMillis());
         return HttpResponseResult.succeed(orderVo);
     }
 

+ 40 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/support/DistributedLock.java

@@ -1,5 +1,7 @@
 package com.yonge.cooleshow.biz.dal.support;
 
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
 import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 import org.slf4j.Logger;
@@ -74,6 +76,43 @@ public class DistributedLock {
     }
 
     /**
+     * 分布式锁-同步
+     *
+     * @param lockName lockKey
+     * @param callable 任务
+     * @param timeout  超时时间
+     * @param unit     超时时间单位
+     * @return Future 异步任务
+     */
+    public <T> T runIfLockCanGet(final String lockName, Callable<T> callable, final long timeout, TimeUnit unit) {
+        RLock lock = redissonClient.getLock(lockName);
+        if (Objects.isNull(lock)) {
+            log.info("callIfLockCanGet lock is null lockName : {}", lockName);
+            return null;
+        }
+        ExecutorService executor = Executors.newCachedThreadPool();
+        try {
+            if (lock.tryLock(0, timeout, unit)) {
+                log.info("callIfLockCanGet lock lockName : {} time is {}", lockName, System.currentTimeMillis());
+                Future<T> submit = executor.submit(callable);
+                return submit.get();
+            } else {
+                return null;
+            }
+        } catch (BizException e) {
+            throw e;
+        } catch (ExecutionException e) {
+            throw new BizException(e.getCause().getMessage());
+        } catch (Exception e) {
+            log.error("callIfLockCanGet error lockKey {}", lockName);
+            throw new RuntimeException("任务执行异常");
+        } finally {
+            executor.shutdown();
+            unlock(lock);
+        }
+    }
+
+    /**
      * 分布式锁-异步
      *
      * @param lockName lockKey
@@ -91,6 +130,7 @@ public class DistributedLock {
         ExecutorService executor = Executors.newCachedThreadPool();
         try {
             if (lock.tryLock(0, timeout, unit)) {
+                log.info("callIfLockCanGet lock lockName : {} time is {}", lockName, System.currentTimeMillis());
                 return executor.submit(callable);
             } else {
                 return null;

+ 2 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/PaymentController.java

@@ -98,4 +98,6 @@ public class PaymentController extends BaseController {
             e.printStackTrace();
         }
     }
+    //支付宝授权回调地址
+    //aliCallback
 }

+ 14 - 19
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/UserOrderController.java

@@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderPayReq;
-import com.yonge.cooleshow.biz.dal.dto.req.OrderRefundReq;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.search.OrderSearch;
 import com.yonge.cooleshow.biz.dal.entity.UserOrder;
@@ -25,6 +24,8 @@ import com.yonge.toolset.utils.string.StringUtil;
 import com.yonge.toolset.utils.web.WebUtil;
 import io.swagger.annotations.*;
 import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.*;
@@ -37,8 +38,6 @@ import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.temporal.TemporalAdjusters;
 import java.util.Date;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -49,6 +48,8 @@ import java.util.concurrent.TimeUnit;
 @RequestMapping("/userOrder")
 @Api(value = "订单接口", tags = "订单接口")
 public class UserOrderController extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(UserOrderController.class);
+
     @Autowired
     private SysUserFeignService sysUserFeignService;
     @Autowired
@@ -66,15 +67,12 @@ public class UserOrderController extends BaseController {
         orderReq.setUserId(user.getId());
 
         try {
-            Future<HttpResponseResult<UserOrder>> httpResponseResultFuture = DistributedLock.of(redissonClient)
-                    .callIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(user.getId())
+            return DistributedLock.of(redissonClient)
+                    .runIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(user.getId())
                             , () -> userOrderService.executeOrder(orderReq), 60L, TimeUnit.SECONDS);
-            return httpResponseResultFuture.get();
         } catch (BizException e) {
             return HttpResponseResult.failed(e.getMessage());
-        } catch (ExecutionException e) {
-            return HttpResponseResult.failed(e.getCause().getMessage());
-        } catch (Exception e) {
+        }  catch (Exception e) {
             e.printStackTrace();
             return HttpResponseResult.failed("下单失败");
         }
@@ -94,14 +92,11 @@ public class UserOrderController extends BaseController {
         payReq.setIpAddress(WebUtil.getRemoteIp(request));
 
         try {
-            Future<HttpResponseResult<OrderPayRes>> httpResponseResultFuture = DistributedLock.of(redissonClient)
-                    .callIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(user.getId())
+            return DistributedLock.of(redissonClient)
+                    .runIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(user.getId())
                             , () -> userOrderService.orderPay(payReq), 60L, TimeUnit.SECONDS);
-            return httpResponseResultFuture.get();
         } catch (BizException e) {
             return HttpResponseResult.failed(e.getMessage());
-        } catch (ExecutionException e) {
-            return HttpResponseResult.failed(e.getCause().getMessage());
         } catch (Exception e) {
             e.printStackTrace();
             return HttpResponseResult.failed("付款失败");
@@ -151,12 +146,12 @@ public class UserOrderController extends BaseController {
         }
         payReq.setUserId(user.getId());
 
-        Future<HttpResponseResult<Boolean>> httpResponseResultFuture = DistributedLock.of(redissonClient)
-                .callIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(user.getId())
-                        , () -> userOrderService.orderCancel(payReq), 60L, TimeUnit.SECONDS);
-
         try {
-            return httpResponseResultFuture.get();
+            return DistributedLock.of(redissonClient)
+                    .runIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(user.getId())
+                            , () -> userOrderService.orderCancel(payReq), 60L, TimeUnit.SECONDS);
+        } catch (BizException e) {
+            return HttpResponseResult.failed(e.getMessage());
         } catch (Exception e) {
             e.printStackTrace();
             return HttpResponseResult.failed("取消订单失败");

+ 2 - 1
toolset/thirdparty-component/src/main/java/com/yonge/toolset/thirdparty/user/realname/provider/LinkfaceRealnameAuthenticationPlugin.java

@@ -98,7 +98,8 @@ public class LinkfaceRealnameAuthenticationPlugin implements RealnameAuthenticat
                     msg = "查无此身份证号";
                 }
             } else {
-                msg = reason.get(status);
+                //msg = reason.get(status);
+                msg = "身份证号和姓名不一致";
             }
             throw new ThirdpartyException("实名认证失败,原因:{}", msg);
         }

+ 16 - 0
toolset/toolset-payment/payment-core/pom.xml

@@ -13,7 +13,17 @@
     <packaging>jar</packaging>
     <version>${project.toolset.version}</version>
 
+
+    <properties>
+        <redisson.version>3.16.4</redisson.version>
+    </properties>
+
     <dependencies>
+        <dependency>
+            <groupId>com.yonge.toolset</groupId>
+            <artifactId>toolset-mybatis</artifactId>
+            <version>${project.toolset.version}</version>
+        </dependency>
         <!-- mybatis-plus -->
         <dependency>
             <groupId>com.baomidou</groupId>
@@ -21,5 +31,11 @@
             <version>3.0.7.1</version>
             <scope>provided</scope>
         </dependency>
+        <!-- redisson -->
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson-spring-boot-starter</artifactId>
+            <version>${redisson.version}</version>
+        </dependency>
     </dependencies>
 </project>

+ 9 - 0
toolset/toolset-payment/payment-core/src/main/java/com/yonge/toolset/payment/core/dao/SysConfigPaymentDao.java

@@ -0,0 +1,9 @@
+package com.yonge.toolset.payment.core.dao;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yonge.toolset.payment.core.entity.SysConfigPayment;
+
+public interface SysConfigPaymentDao extends BaseMapper<SysConfigPayment> {
+
+}

+ 95 - 0
toolset/toolset-payment/payment-core/src/main/java/com/yonge/toolset/payment/core/entity/SysConfigPayment.java

@@ -0,0 +1,95 @@
+package com.yonge.toolset.payment.core.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * 支付服务配置参数
+ */
+@TableName("sys_config_payment")
+public class SysConfigPayment implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id_", type = IdType.AUTO)
+    private Long id;
+	@TableField(value = "open_type_")
+    private String openType;
+	@TableField(value = "param_name_")
+    private String paramName;
+	@TableField(value = "param_value_")
+    private String paramValue;
+	@TableField(value = "description_")
+    private String description;
+	@TableField(value = "create_time_")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date createTime;
+	@TableField(value = "update_time_")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date updateTime;
+
+	public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+    
+	public String getOpenType() {
+        return openType;
+    }
+
+    public void setOpenType(String openType) {
+        this.openType = openType;
+    }
+    
+	public String getParamName() {
+        return paramName;
+    }
+
+    public void setParamName(String paramName) {
+        this.paramName = paramName;
+    }
+    
+	public String getParamValue() {
+        return paramValue;
+    }
+
+    public void setParamValue(String paramValue) {
+        this.paramValue = paramValue;
+    }
+    
+	public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+    
+	public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+    
+	public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+    
+}

+ 22 - 0
toolset/toolset-payment/payment-core/src/main/java/com/yonge/toolset/payment/core/service/SysConfigPaymentService.java

@@ -0,0 +1,22 @@
+package com.yonge.toolset.payment.core.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.toolset.payment.core.entity.SysConfigPayment;
+import com.yonge.toolset.payment.core.enums.OpenEnum;
+
+/**
+ * 支付服务配置参数 服务类
+ * @author liweifan
+ * @date 2022-05-10
+ */
+public interface SysConfigPaymentService extends IService<SysConfigPayment>  {
+	/***
+	 * 获取支付配置
+	 * @author liweifan
+	 * @param: openType 支付服务提供方
+	 * @param: paramName 配置名称
+	 * @updateTime 2022/5/10 22:55
+	 * @return: com.yonge.toolset.payment.core.entity.SysConfigPayment
+	 */
+	SysConfigPayment getPaymentConfig(OpenEnum openType,String paramName);
+}

+ 53 - 0
toolset/toolset-payment/payment-core/src/main/java/com/yonge/toolset/payment/core/service/impl/SysConfigPaymentServiceImpl.java

@@ -0,0 +1,53 @@
+package com.yonge.toolset.payment.core.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.toolset.payment.core.dao.SysConfigPaymentDao;
+import com.yonge.toolset.payment.core.entity.SysConfigPayment;
+import com.yonge.toolset.payment.core.enums.OpenEnum;
+import com.yonge.toolset.payment.core.service.SysConfigPaymentService;
+import com.yonge.toolset.utils.string.StringUtil;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.PostConstruct;
+import java.util.List;
+
+
+@Service
+public class SysConfigPaymentServiceImpl extends ServiceImpl<SysConfigPaymentDao, SysConfigPayment> implements SysConfigPaymentService {
+
+    private final static Logger log = LoggerFactory.getLogger(SysConfigPaymentServiceImpl.class);
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    private static final String REDIS_KEY = "CONFIG_PAYMENT";
+
+    @PostConstruct
+    private void init() {
+        List<SysConfigPayment> sysConfigPayments = baseMapper.selectList(Wrappers.emptyWrapper());
+        for (SysConfigPayment configPayment : sysConfigPayments) {
+            redissonClient.getBucket(REDIS_KEY + ":" + configPayment.getOpenType()+ ":" + configPayment.getParamName()).set(configPayment);
+        }
+    }
+
+    @Override
+    public SysConfigPayment getPaymentConfig(OpenEnum openType, String paramName) {
+        if (null == openType || StringUtil.isEmpty(paramName)) {
+            return null;
+        }
+        SysConfigPayment configPayment = (SysConfigPayment) redissonClient.getBucket(REDIS_KEY + ":" + openType.getCode() + ":" + paramName).get();
+        if (null == configPayment) {
+            configPayment = baseMapper.selectOne(Wrappers.<SysConfigPayment>lambdaQuery()
+                    .eq(SysConfigPayment::getOpenType, openType.getCode())
+                    .eq(SysConfigPayment::getParamName, paramName)
+            );
+            redissonClient.getBucket(REDIS_KEY + ":" + openType.getCode() + ":" + paramName).set(configPayment);
+        }
+        return configPayment;
+    }
+}