| | |
| | | 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; |
| | | |
| | |
| | | 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)) { |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |
| | | |