采购提交与报销新建/提交事务显式使用10秒上限 [09-27-purchase-submit-tx-timeout]

负载下采购提交事务超过 Prisma 交互事务默认 5000ms(P2028)返回 500。
分段计时显示无单一瓶颈(总时长中位 843ms、最大 3506ms,编号锁等待
最多 535ms),是约 20 条顺序查询整体变慢贴近上限。报销新建/提交同结构。
三处改用项目既有的 { maxWait: 5000, timeout: 10000 },事务内容不变;
新增采购与报销提交的事务选项回归断言。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
2026-09-27 12:27:04 +08:00
共同撰写人 Claude Opus 5.5
父节点 a6ff2dc3b1
当前提交 b6f0c83608
共修改 9 个文件,包含 92 行新增和 4 行删除
+3 -1
查看文件
@@ -1701,6 +1701,8 @@ async function purchaseRequestRoutes(fastify, options = {}) {
throw buildBusinessValidationError("purchase_request.approver_unavailable", { workflow: "no_actionable_approver" }, 409);
}
// ~20 sequential queries plus document numbering; under load this exceeded
// Prisma's 5s interactive-transaction default (P2028 -> 500).
const submitResult = await fastify.prisma.$transaction(async (tx) => {
const locked = await loadPurchaseRequestForUpdate(tx, purchaseRequestId);
ensureDraftOwner(request, locked);
@@ -1949,7 +1951,7 @@ async function purchaseRequestRoutes(fastify, options = {}) {
budgetReservation,
},
};
});
}, { maxWait: 5000, timeout: 10000 });
void fastify.prisma.auditLog.create({
data: buildAuditLogData(request, {
+2 -2
查看文件
@@ -1863,7 +1863,7 @@ async function reimbursementRoutes(fastify) {
...created,
items: createdItems,
};
});
}, { maxWait: 5000, timeout: 10000 });
return sendData(reply, request, {
id: reimbursement.id,
@@ -4498,7 +4498,7 @@ async function reimbursementRoutes(fastify) {
actorId: request.employee.id,
},
};
});
}, { maxWait: 5000, timeout: 10000 });
await finalizeReimbursementSubmitSideEffects({
prisma: fastify.prisma,