fix(kuaishou-industry): 修复电子凭证发货回调并发导致 807000 获取并发锁失败

同一 oid 的发货回调可能被多个来源并发调度(内存重试链 timer、worker_scan
兜底扫描、快手重复推送 send-code 后的再次调度),快手侧对同一 oid 有并发锁,
并发请求会返回 807000「获取并发锁失败」。

- runKuaishouIndustrySendCallbackForOid 增加进程内 in-flight 互斥,
  正在执行时其它调度直接跳过,由当前执行链路决定成功或按 backoff 重试
  (try/finally 保证所有 return 路径释放)
- listKuaishouIndustryVouchersForSendCallbackRetry 增加 maxAttempts 参数
  及 SQL 条件 COALESCE(send_callback_attempt_count,0) < ,缩小扫描集
This commit is contained in:
yml2213
2026-08-05 20:05:43 +08:00
parent 4e9c416235
commit e8eab6e689
2 changed files with 187 additions and 125 deletions
@@ -203,16 +203,18 @@ export async function listKuaishouIndustryVouchersByOid(
export async function listKuaishouIndustryVouchersForSendCallbackRetry(
limit = 100,
maxAttempts = 8,
): Promise<KuaishouIndustryVoucherRow[]> {
const result = await query<KuaishouIndustryVoucherRow>(
`
SELECT *
FROM kuaishou_industry_vouchers
WHERE send_callback_status <> 'success'
AND COALESCE(send_callback_attempt_count, 0) < $2
ORDER BY COALESCE(send_callback_sent_at, created_at) ASC, id ASC
LIMIT $1
`,
[normalizePositiveLimit(limit, 100)],
[normalizePositiveLimit(limit, 100), Math.max(1, Math.trunc(Number(maxAttempts) || 8))],
)
return result.rows
@@ -277,7 +279,9 @@ export async function listKuaishouIndustryVouchersForAdmin(
where.push(`v.seller_id = $${params.length}`)
}
const status = String(input.status || '').trim().toUpperCase()
const status = String(input.status || '')
.trim()
.toUpperCase()
if (status) {
params.push(status)
where.push(`v.status = $${params.length}`)