Преглед изворни кода

订单获取序列号加锁以解决订单序列号重复问题

codingliang пре 1 година
родитељ
комит
ae79b45458

+ 38 - 19
src/main/java/com/sqx/modules/order/service/impl/AppAppOrderServiceImpl.java

@@ -593,15 +593,6 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
         // 用户信息
         UserEntity userEntity = userDao.selectById(order.getUserId());
 
-        // 添加消息记录并且进行推送
-        MyGlobalThreadPool.execute(() -> {
-            try {
-                addOrderMessageAndPush(order, goodsShop, mpPushConfig, userEntity);
-            } catch (Exception e) {
-                log.error("订单:{},订单支付成功通知发送失败,失败原因:{}", order.getOrderId(), e);
-            }
-        });
-
         // 是否自动接单
         boolean autoAccept = goodsShop.getAutoAcceptOrder() != null && goodsShop.getAutoAcceptOrder() == 0;
         // 是否预约订单
@@ -617,20 +608,48 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
             order.setStatus(7);
         }
 
-        // 计算订单顺序号
-        order.setOrderSequence(String.format("%04d", selectCurrentOrderSequenceByShopId(order, order.getShopId())));
+        RLock lock = redissonClient.getLock(String.format(RedisKey.UPDATE_ORDER_LOCK, order.getOrderId()));
+        lock.lock();
+        TransactionStatus status = null;
+        try {
+            // 开启编程式事务
+            status = transactionManager.getTransaction(new DefaultTransactionDefinition());
 
-        // 更新订单状态
-        updateById(order);
+            // 计算订单顺序号
+            order.setOrderSequence(String.format("%04d", selectCurrentOrderSequenceByShopId(order, order.getShopId())));
+
+            // 更新订单状态
+            updateById(order);
+
+            // 扣减库存
+            this.subStock(order);
 
-        // 扣减库存
-        this.subStock(order);
+            // 优惠券变成已使用状态
+            updateCouponState(order);
 
-        // 优惠券变成已使用状态
-        updateCouponState(order);
+            // 如果是支付宝或者微信支付,用户钱包新增消费记录
+            addConsumeRecordInUserMoneyDetail(order);
 
-        // 如果是支付宝或者微信支付,用户钱包新增消费记录
-        addConsumeRecordInUserMoneyDetail(order);
+            // 在锁中提交事务
+            transactionManager.commit(status);
+        } catch (Exception e) {
+            if (ObjectUtil.isNotNull(status)) {
+                transactionManager.rollback(status);
+            }
+            log.error("订单【{}】支付成功状态修改失败,异常信息【{}】", order.getOrderId(), e.getMessage());
+            throw new SqxException("订单状态修改失败," + e);
+        } finally {
+            lock.unlock();
+        }
+
+        // 添加消息记录并且进行推送
+        MyGlobalThreadPool.execute(() -> {
+            try {
+                addOrderMessageAndPush(order, goodsShop, mpPushConfig, userEntity);
+            } catch (Exception e) {
+                log.error("订单:{},订单支付成功通知发送失败,失败原因:{}", order.getOrderId(), e);
+            }
+        });
 
         // 已接单状态的订单生成跑腿订单
         if (order.getStatus() == 6) {