瀏覽代碼

@
fix: saveBillBase 并发竞态 — DuplicateKeyException 时回退 UPDATE

同一 pay_no 的 COLLECT + ASSETS_UPDATE 通知并发到达时,
两个线程都 SELECT 不到记录,先后 INSERT 造成唯一索引冲突。
catch DuplicateKeyException 后重新查出已存在记录并走 UPDATE。
@

alphaH 11 小時之前
父節點
當前提交
b72a94fc3d

+ 14 - 1
java/src/main/java/com/payment/platform/module/payment/notification/handler/BillHandler.java

@@ -28,6 +28,7 @@ import com.payment.platform.module.payment.notification.mapper.PayBillVoucherMap
 import com.payment.platform.module.payment.openapi.service.OpenapiService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DuplicateKeyException;
 import org.springframework.stereotype.Component;
 
 import java.math.BigDecimal;
@@ -239,7 +240,19 @@ public class BillHandler extends BaseNotifyHandler {
         if (existing != null) {
             payBillMapper.updateById(bill);
         } else {
-            payBillMapper.insert(bill);
+            try {
+                payBillMapper.insert(bill);
+            } catch (DuplicateKeyException e) {
+                // 并发:另一条通知(同一pay_no)抢先插入 → 重新查出已存在记录并更新
+                PayBillEntity dup = payBillMapper.selectOne(
+                        new LambdaQueryWrapper<PayBillEntity>().eq(PayBillEntity::getPayNo, payNo));
+                if (dup != null) {
+                    bill.setId(dup.getId());
+                    payBillMapper.updateById(bill);
+                } else {
+                    throw e;
+                }
+            }
         }
         log.info("保存账单基础数据: pay_no={}, type={}, amount={}, employee_id={}",
                 payNo, consumeType, consumeAmount, employeeId);