فهرست منبع

修复两个用户同时操作购物车导致订单金额异常bug

codingliang 1 سال پیش
والد
کامیت
5b82da2ff1

+ 0 - 1
src/main/java/com/sqx/modules/errand/service/impl/TbIndentServiceImpl.java

@@ -923,7 +923,6 @@ public class TbIndentServiceImpl extends ServiceImpl<TbIndentDao, TbIndent> impl
     }
     }
 
 
     @Override
     @Override
-    @Transactional
     public Result riderDelivery(Long userId, RiderDeliveryDTO deliveryDTO) {
     public Result riderDelivery(Long userId, RiderDeliveryDTO deliveryDTO) {
         // 添加拍照发短信逻辑
         // 添加拍照发短信逻辑
         // 因为原有的确认送达方法代码比较凌乱,且不好重新封装,所以这里就在原有确认收货方法之前添加拍照发短信逻辑
         // 因为原有的确认送达方法代码比较凌乱,且不好重新封装,所以这里就在原有确认收货方法之前添加拍照发短信逻辑

+ 17 - 4
src/main/java/com/sqx/modules/order/service/impl/AppAppOrderServiceImpl.java

@@ -84,9 +84,13 @@ import org.redisson.api.RedissonClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionStatus;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.support.DefaultTransactionDefinition;
 
 
+import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.text.SimpleDateFormat;
@@ -162,15 +166,14 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
     private TbIndentSmsSendLogService smsSendLogService;
     private TbIndentSmsSendLogService smsSendLogService;
     @Autowired
     @Autowired
     private TbIndentSmsTemplateService smsTemplateService;
     private TbIndentSmsTemplateService smsTemplateService;
-
     @Autowired
     @Autowired
+    private PlatformTransactionManager transactionManager;
+
+    @Resource
     private RedissonClient redissonClient;
     private RedissonClient redissonClient;
 
 
     private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern(DateUtils.TIME_PATTERN1);
     private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern(DateUtils.TIME_PATTERN1);
 
 
-
-
-    @Transactional
     @Override
     @Override
     public void insertOrder(Long userId, Long shopId, Long goodsId, Integer num, Long skuId, String skuMessage, Integer orderType) {
     public void insertOrder(Long userId, Long shopId, Long goodsId, Integer num, Long skuId, String skuMessage, Integer orderType) {
         // 判断当前时间是否在店铺营业范围内
         // 判断当前时间是否在店铺营业范围内
@@ -190,6 +193,9 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
             TbOrder order = appOrderDao.selectOne(new QueryWrapper<TbOrder>().eq("user_id", userId).eq("shop_id", shopId).eq("status", 1));
             TbOrder order = appOrderDao.selectOne(new QueryWrapper<TbOrder>().eq("user_id", userId).eq("shop_id", shopId).eq("status", 1));
             Goods goods = goodsDao.selectById(goodsId);
             Goods goods = goodsDao.selectById(goodsId);
             String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
             String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
+
+            // 开启编程式事务
+            TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
             if (order == null) {
             if (order == null) {
                 UserEntity userEntity = userDao.selectById(userId);
                 UserEntity userEntity = userDao.selectById(userId);
                 TbOrder tbOrder = new TbOrder();
                 TbOrder tbOrder = new TbOrder();
@@ -254,6 +260,9 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
                 tbOrder1.setAddGoodsTime(format);
                 tbOrder1.setAddGoodsTime(format);
                 appOrderDao.updateById(tbOrder1);
                 appOrderDao.updateById(tbOrder1);
             }
             }
+
+            // 在锁中提交事务
+            transactionManager.commit(status);
         } finally {
         } finally {
             lock.unlock();
             lock.unlock();
         }
         }
@@ -387,6 +396,10 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
             throw new SqxException("无效的订单id");
             throw new SqxException("无效的订单id");
         }
         }
 
 
+        if (parentOrder.getIsPay() == 1) {
+            throw new SqxException("当前订单已支付,请勿重复支付!");
+        }
+
         // 获取店铺信息
         // 获取店铺信息
         // 注意:调用shopMessageService获取店铺信息,这个service对店铺的抽成比例有特殊处理(历史代码就是如此/(ㄒoㄒ)/~~)
         // 注意:调用shopMessageService获取店铺信息,这个service对店铺的抽成比例有特殊处理(历史代码就是如此/(ㄒoㄒ)/~~)
         GoodsShop goodsShop = shopMessageService.selectShopId(parentOrder.getShopId());
         GoodsShop goodsShop = shopMessageService.selectShopId(parentOrder.getShopId());

+ 32 - 22
src/main/java/com/sqx/modules/pay/service/impl/WxServiceImpl.java

@@ -98,10 +98,12 @@ public class WxServiceImpl implements WxService {
 
 
     @Override
     @Override
     public Result balanceOrder(Long userId, PayOrderDTO payOrderDTO) {
     public Result balanceOrder(Long userId, PayOrderDTO payOrderDTO) {
-        RLock lock = redissonClient.getLock(String.format(RedisKey.PAY_ORDER_LOCK, payOrderDTO.getParentId()));
+        TbOrder tbOrder = appOrderService.prepareOrder(userId, payOrderDTO);
+
+        RLock lock = redissonClient.getLock(String.format(RedisKey.INSERT_ORDER_LOCK, tbOrder.getOrderId(), tbOrder.getShopId()));
         lock.lock();
         lock.lock();
         try{
         try{
-            return balanceOrders(userId, payOrderDTO);
+            return balanceOrders(userId, tbOrder);
         } finally {
         } finally {
             lock.unlock();
             lock.unlock();
         }
         }
@@ -111,10 +113,7 @@ public class WxServiceImpl implements WxService {
      * 钱包支付订单
      * 钱包支付订单
      */
      */
     @Transactional
     @Transactional
-    public Result balanceOrders(Long userId, PayOrderDTO payOrderDTO){
-        // 获取订单信息
-        TbOrder tbOrder = appOrderService.prepareOrder(userId, payOrderDTO);
-
+    public Result balanceOrders(Long userId, TbOrder tbOrder){
         // 扣除用户余额
         // 扣除用户余额
         BigDecimal payMoney = tbOrder.getPayMoney();
         BigDecimal payMoney = tbOrder.getPayMoney();
         UserMoney userMoney = userMoneyService.selectUserMoneyByUserId(userId);
         UserMoney userMoney = userMoneyService.selectUserMoneyByUserId(userId);
@@ -217,25 +216,36 @@ public class WxServiceImpl implements WxService {
 
 
         // 设置支付方式 1表示微信支付、4或5表示支付宝支付
         // 设置支付方式 1表示微信支付、4或5表示支付宝支付
         Integer type = payOrderDTO.getType();
         Integer type = payOrderDTO.getType();
-        tbOrder.setPayType(1);
-        if(type== 4 || type== 5){
-            tbOrder.setPayType(3);
-        }
 
 
-        // 设置订单号
-        if (StrUtil.isBlank(tbOrder.getOrderNumber())) {
-            tbOrder.setOrderNumber(getGeneralOrder());
-        }
+        RLock lock = redissonClient.getLock(String.format(RedisKey.INSERT_ORDER_LOCK, tbOrder.getUserId(), tbOrder.getShopId()));
+        lock.lock();
+        try {
+
+            tbOrder.setPayType(1);
+            if(type == 4 || type == 5){
+                tbOrder.setPayType(3);
+            }
 
 
-        // 保存订单信息
-        appOrderDao.updateById(tbOrder);
+            // 设置订单号
+            if (StrUtil.isBlank(tbOrder.getOrderNumber())) {
+                tbOrder.setOrderNumber(getGeneralOrder());
+            }
 
 
-        if (tbOrder.getPayType() == 1) {
-            // 微信支付
-            return pay(tbOrder.getPayMoney().doubleValue(), type, tbOrder.getUserId(), tbOrder.getOrderNumber(), 1);
-        } else {
-            // 支付宝支付
-            return aliPayController.payAppOrders(tbOrder.getPayMoney().doubleValue(), type, tbOrder.getUserId(), tbOrder.getOrderNumber(), 1);
+            // 支付时,订单状态改为 0
+            tbOrder.setStatus(0);
+
+            // 保存订单信息
+            appOrderDao.updateById(tbOrder);
+
+            if (tbOrder.getPayType() == 1) {
+                // 微信支付
+                return pay(tbOrder.getPayMoney().doubleValue(), type, tbOrder.getUserId(), tbOrder.getOrderNumber(), 1);
+            } else {
+                // 支付宝支付
+                return aliPayController.payAppOrders(tbOrder.getPayMoney().doubleValue(), type, tbOrder.getUserId(), tbOrder.getOrderNumber(), 1);
+            }
+        } finally {
+            lock.unlock();
         }
         }
     }
     }