From 338321b3a2d7e09dbf6b76ca60ceea4da10efa75 Mon Sep 17 00:00:00 2001 From: hailin Date: Sun, 1 Feb 2026 03:29:27 -0800 Subject: [PATCH] =?UTF-8?q?fix(c2c):=20=E7=94=A8updateMany+status=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E9=98=B2=E6=AD=A2=E5=90=88=E5=B9=B6=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E7=AB=9E=E6=80=81=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit findFirst找到PENDING订单后,如果被takeOrder接走(状态变MATCHED), updateMany因status!=PENDING返回count=0,自动回退到创建新订单。 Co-Authored-By: Claude Opus 4.5 --- .../src/application/services/c2c.service.ts | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/backend/services/trading-service/src/application/services/c2c.service.ts b/backend/services/trading-service/src/application/services/c2c.service.ts index 69852dc2..6d6da83b 100644 --- a/backend/services/trading-service/src/application/services/c2c.service.ts +++ b/backend/services/trading-service/src/application/services/c2c.service.ts @@ -785,7 +785,7 @@ export class C2cService { const priceDecimal = new Decimal(freshOrder.price); // 查找是否已有可合并的 PENDING 订单(同 maker + 同类型 + 同价格) - const existingPending = await tx.c2cOrder.findFirst({ + let existingPending = await tx.c2cOrder.findFirst({ where: { makerAccountSequence: freshOrder.makerAccountSequence, type: freshOrder.type as any, @@ -799,21 +799,35 @@ export class C2cService { const existingQty = new Decimal(existingPending.quantity.toString()); const mergedQty = existingQty.plus(quantityDecimal); const mergedTotal = priceDecimal.mul(mergedQty).toString(); - restoreOrderNo = existingPending.orderNo; this.logger.log( - `[EXPIRY][TX] 步骤3: 合并到已有 PENDING 订单 ${existingPending.orderNo}, ` + + `[EXPIRY][TX] 步骤3: 尝试合并到 PENDING 订单 ${existingPending.orderNo}, ` + `原数量=${existingQty} + 恢复=${quantityDecimal} = ${mergedQty}`, ); - await tx.c2cOrder.update({ - where: { orderNo: existingPending.orderNo }, + // 用 updateMany + status 条件防止竞态:如果订单在 findFirst 后被 takeOrder 接走,count=0 + const updateResult = await tx.c2cOrder.updateMany({ + where: { + orderNo: existingPending.orderNo, + status: C2C_ORDER_STATUS.PENDING as any, + }, data: { quantity: mergedQty.toString(), totalAmount: mergedTotal, }, }); - } else { + + if (updateResult.count > 0) { + restoreOrderNo = existingPending.orderNo; + this.logger.log(`[EXPIRY][TX] 步骤3: 合并成功`); + } else { + // 订单已被接走(状态不再是 PENDING),回退到创建新订单 + this.logger.warn(`[EXPIRY][TX] 步骤3: 订单 ${existingPending.orderNo} 已被接走,改为创建新订单`); + existingPending = null; // fall through to create + } + } + + if (shouldRestore && !restoreOrderNo) { // 无可合并订单,创建新的 PENDING 订单 restoreOrderNo = this.generateOrderNo(); const totalAmount = priceDecimal.mul(quantityDecimal).toString();