cl
2 天以前 b47369fbc73269f0661ba169c6387e04fb037e87
src/main/java/com/zy/asrs/controller/SaleOrderController.java
@@ -21,6 +21,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DeadlockLoserDataAccessException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -361,38 +362,60 @@
        return Math.abs(d1 - d2) < 0.0001;
    }
    /** 死锁重试次数 */
    private static final int CUST_WAIT_PAKIN_DEADLOCK_RETRIES = 2;
    /** 死锁重试间隔(毫秒) */
    private static final int CUST_WAIT_PAKIN_RETRY_DELAY_MS = 80;
    /**
     * 销售订单数量更新后,顺带更新 cust_wait_pakin 的 anfme/nqty(mobile/bill/query 的 count 取自 anfme)。
     * 仅按 matnr+mnemonic 更新,不插入;无匹配或异常不影响主流程。
     * 发生死锁时自动重试,减少并发更新导致的死锁牺牲。
     */
    private void updateWaitPakinQuantity(Map<String, Object> data) {
        try {
            String invCode = data.get("invCode") != null ? String.valueOf(data.get("invCode")).trim() : null;
            String orderCode = data.get("orderCode") != null ? String.valueOf(data.get("orderCode")).trim() : null;
            if (Cools.isEmpty(invCode) || Cools.isEmpty(orderCode)) {
                logger.debug("cust_wait_pakin 跳过更新:订单号或物料编码为空,orderCode={},invCode={}", orderCode, invCode);
        String invCode = data.get("invCode") != null ? String.valueOf(data.get("invCode")).trim() : null;
        String orderCode = data.get("orderCode") != null ? String.valueOf(data.get("orderCode")).trim() : null;
        if (Cools.isEmpty(invCode) || Cools.isEmpty(orderCode)) {
            logger.debug("cust_wait_pakin 跳过更新:订单号或物料编码为空,orderCode={},invCode={}", orderCode, invCode);
            return;
        }
        Double productQty = parseDoubleSafely(data.get("productQty"));
        if (productQty == null) {
            productQty = parseDoubleSafely(data.get("orderQty"));
        }
        logger.info("cust_wait_pakin 开始更新:订单号={},物料编码={},数量={}", orderCode, invCode, productQty);
        String invName = data.get("invName") != null ? String.valueOf(data.get("invName")) : null;
        WaitPakin updateEntity = new WaitPakin();
        updateEntity.setMaktx(invName);
        updateEntity.setAnfme(productQty);
        updateEntity.setNqty(productQty);
        updateEntity.setModiTime(new Date());
        Wrapper<WaitPakin> wrapper = new EntityWrapper<WaitPakin>().eq("matnr", invCode).eq("mnemonic", orderCode);
        for (int attempt = 0; attempt <= CUST_WAIT_PAKIN_DEADLOCK_RETRIES; attempt++) {
            try {
                boolean updated = waitPakinService.update(updateEntity, wrapper);
                if (updated) {
                    logger.info("cust_wait_pakin 更新成功:订单号={},物料编码={},数量={}", orderCode, invCode, productQty);
                } else {
                    logger.warn("cust_wait_pakin 更新未影响行(可能无匹配记录):订单号={},物料编码={}", orderCode, invCode);
                }
                return;
            } catch (Exception e) {
                if (e instanceof DeadlockLoserDataAccessException || (e.getCause() != null && e.getCause().getClass().getSimpleName().contains("Deadlock"))) {
                    if (attempt < CUST_WAIT_PAKIN_DEADLOCK_RETRIES) {
                        try {
                            Thread.sleep(CUST_WAIT_PAKIN_RETRY_DELAY_MS);
                        } catch (InterruptedException ie) {
                            Thread.currentThread().interrupt();
                        }
                        logger.warn("cust_wait_pakin 更新死锁,第{}次重试:订单号={},物料编码={}", attempt + 1, orderCode, invCode);
                        continue;
                    }
                }
                logger.error("cust_wait_pakin 更新异常:orderCode={},invCode={},error={}", data.get("orderCode"), data.get("invCode"), e.getMessage(), e);
                return;
            }
            Double productQty = parseDoubleSafely(data.get("productQty"));
            if (productQty == null) {
                productQty = parseDoubleSafely(data.get("orderQty"));
            }
            logger.info("cust_wait_pakin 开始更新:订单号={},物料编码={},数量={}", orderCode, invCode, productQty);
            String invName = data.get("invName") != null ? String.valueOf(data.get("invName")) : null;
            WaitPakin updateEntity = new WaitPakin();
            updateEntity.setMaktx(invName);
            updateEntity.setAnfme(productQty);
            updateEntity.setNqty(productQty);
            updateEntity.setModiTime(new Date());
            Wrapper<WaitPakin> wrapper = new EntityWrapper<WaitPakin>().eq("matnr", invCode).eq("mnemonic", orderCode);
            boolean updated = waitPakinService.update(updateEntity, wrapper);
            if (updated) {
                logger.info("cust_wait_pakin 更新成功:订单号={},物料编码={},数量={}", orderCode, invCode, productQty);
            } else {
                logger.warn("cust_wait_pakin 更新未影响行(可能无匹配记录):订单号={},物料编码={}", orderCode, invCode);
            }
        } catch (Exception e) {
            logger.error("cust_wait_pakin 更新异常:orderCode={},invCode={},error={}", data.get("orderCode"), data.get("invCode"), e.getMessage(), e);
        }
    }