Sfoglia il codice sorgente

新增redis秒杀库春控制

赵冬冬 4 anni fa
parent
commit
1d8da8ebcd

+ 1 - 0
forest-admin/admin-server/src/main/resources/dao/OmsOrderDao.xml

@@ -32,6 +32,7 @@
             OR receiver_phone LIKE concat("%",#{queryParam.receiverKeyword},"%")
             )
         </if>
+        order by id desc
     </select>
     <update id="delivery">
         UPDATE oms_order

+ 7 - 0
forest-portal/portal-server/pom.xml

@@ -126,10 +126,17 @@
                 </exclusion>
             </exclusions>
         </dependency>
+        <!--redis-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson</artifactId>
+            <version>3.5.0</version>
+        </dependency>
+        <!--redis-->
         <!--集成消息队列-->
         <dependency>
             <groupId>org.springframework.boot</groupId>

+ 34 - 0
forest-portal/portal-server/src/main/java/com/hwrj/cloud/portal/config/redis/RedissonConfig.java

@@ -0,0 +1,34 @@
+package com.hwrj.cloud.portal.config.redis;
+
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.redisson.config.Config;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+
+/**
+ * redisson通用化配置
+ **/
+@Configuration
+public class RedissonConfig {
+    @Autowired
+    private Environment env;
+
+    @Value("${myredis.address}")
+    private String address;
+    @Value("${myredis.passord}")
+    private String password;
+
+    @Bean
+    public RedissonClient redissonClient() {
+        Config config = new Config();
+        config.useSingleServer()
+                .setAddress(address)
+                .setPassword(password);
+        RedissonClient client = Redisson.create(config);
+        return client;
+    }
+}

+ 34 - 12
forest-portal/portal-server/src/main/java/com/hwrj/cloud/portal/service/impl/OmsPortalOrderServiceImpl.java

@@ -16,6 +16,8 @@ import com.hwrj.cloud.portal.service.*;
 import com.hwrj.cloud.portal.util.MemberUtil;
 import com.hwrj.cloud.security.service.RedisService;
 import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -356,8 +358,10 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
         //发送延迟消息
         cancelOrderSender.sendMessage(orderId, delayTimes);
     }
+
     @Autowired
-    private  OmsOrderOperateHistoryMapper omsOrderOperateHistoryMapper;
+    private OmsOrderOperateHistoryMapper omsOrderOperateHistoryMapper;
+
     @Override
     public void confirmReceiveOrder(Long orderId) {
         // redis 用户信息
@@ -373,7 +377,7 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
         order.setConfirmStatus(1);
         order.setReceiveTime(new Date());
         orderMapper.updateByPrimaryKey(order);
-        OmsOrderOperateHistory record=new OmsOrderOperateHistory();
+        OmsOrderOperateHistory record = new OmsOrderOperateHistory();
         record.setCreateTime(new Date());
         record.setOrderId(orderId);
         record.setOperateMan(member.getNickname());
@@ -457,16 +461,35 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
     @Autowired
     private PmsProductMapper pmsProductMapper;
 
+    @Autowired
+    private RedissonClient redissonClient;
+    //商品秒杀核心业务逻辑的处理-redisson的分布式锁
+
     @Override
     @Transactional
     public Map<String, Object> save(OrderFrom orderFrom) {
-        PmsProduct pmsProduct = pmsProductMapper.selectByPrimaryKey(orderFrom.getProductId());
-        //新增购物车
-        OmsCartItem cartItem = new OmsCartItem();
-        //构建订单数据
-        OrderParam orderParam = getOrderParam(orderFrom, pmsProduct, cartItem);
-        //下单
-        return saveOrder(orderParam, orderFrom);
+        Long productId = orderFrom.getProductId();
+        String key = "dec_store_lock_" + productId;
+        RLock lock = redissonClient.getLock(key);
+        boolean locked = lock.isLocked();
+        try {
+            //加锁 操作很类似Java的ReentrantLock机制
+            lock.lock();
+            PmsProduct pmsProduct = pmsProductMapper.selectByPrimaryKey(orderFrom.getProductId());
+            //新增购物车
+            OmsCartItem cartItem = new OmsCartItem();
+            //构建订单数据
+            OrderParam orderParam = getOrderParam(orderFrom, pmsProduct, cartItem);
+            //下单
+            return saveOrder(orderParam, orderFrom);
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            Asserts.fail("卖完了!");
+        } finally {
+            //解锁
+            lock.unlock();
+        }
+        return null;
     }
 
     private OrderParam getOrderParam(OrderFrom orderFrom, PmsProduct pmsProduct, OmsCartItem cartItem) {
@@ -1007,15 +1030,14 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
      */
     private void lockStockByOne(List<CartPromotionItem> cartPromotionItemList, OrderFrom orderFrom) {
         for (CartPromotionItem cartPromotionItem : cartPromotionItemList) {
-            PmsProduct record = new PmsProduct();
             PmsProduct pmsProduct = pmsProductMapper.selectByPrimaryKey(cartPromotionItem.getProductId());
             Integer stock = pmsProduct.getStock();
             Integer bayNum = orderFrom.getBayNum();
             if (stock.intValue() < bayNum.intValue()) {
-                Asserts.fail("库存不足,无法下单");
+                Asserts.fail("库存不足,无法下单!");
             }
             pmsProduct.setStock(stock - bayNum);
-            pmsProductMapper.updateByPrimaryKey(record);
+            pmsProductMapper.updateByPrimaryKey(pmsProduct);
         }
     }