-- 编号让位(2026-09-17):本文件原为 V149,与远端已推送的 V149__clear_service_hero_placeholders 撞号,本地让号改为 V152。
|
-- 支付尝试按「这一次尝试」收敛所需要的两列(判定见 docs/adr/0003)。
|
--
|
-- last_reconciled_at 对账任务的公平轮转与退避依据。旧实现按「最早 100 条」取未决流水,一旦积压
|
-- 超过上限,最新出现的那笔(也就是用户刚卡住的那笔)永远轮不到——而死锁唯一
|
-- 的自愈通道就是对账。改为「空值优先、升序、带退避」之后每笔都会轮到。
|
-- close_attempts 关单重试计数。关单回执说「处理中」时支付尝试落在 CLOSING,后台每分钟重试
|
-- 一次;到上限就不再重试(保留 CANCEL_UNCONFIRMED 盯防与问题记录),避免一条
|
-- 坏数据让后台永远重试同一笔。
|
--
|
-- 这两列必须同样落到开发库:开发库(局域网共享的 talent_card)Flyway 是关闭的、结构不由迁移维护,
|
-- 所以另有 scripts/dev-schema-v149-payment-attempt.sql(可手工执行的等价 DDL)与
|
-- scripts/apply-dev-schema.ps1(本机没有 mysql 客户端,用项目已有的 JDBC 驱动执行)。
|
--
|
-- 用存储过程按 exists 判断逐列追加,使脚本可以重复执行(本地开发的库常常手工加过列)。
|
DROP PROCEDURE IF EXISTS add_payment_attempt_convergence_columns;
|
DELIMITER //
|
CREATE PROCEDURE add_payment_attempt_convergence_columns()
|
BEGIN
|
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
WHERE table_schema = DATABASE() AND table_name = 'payment_transaction'
|
AND column_name = 'last_reconciled_at') THEN
|
ALTER TABLE payment_transaction
|
ADD COLUMN last_reconciled_at DATETIME DEFAULT NULL COMMENT '最近一次对账处理时间(公平轮转与退避依据)';
|
END IF;
|
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
WHERE table_schema = DATABASE() AND table_name = 'payment_transaction'
|
AND column_name = 'close_attempts') THEN
|
ALTER TABLE payment_transaction
|
ADD COLUMN close_attempts INT NOT NULL DEFAULT 0 COMMENT '已发出的关单请求次数(重试上限依据)';
|
END IF;
|
IF NOT EXISTS (SELECT 1 FROM information_schema.statistics
|
WHERE table_schema = DATABASE() AND table_name = 'payment_transaction'
|
AND index_name = 'idx_payment_transaction_reconcile') THEN
|
CREATE INDEX idx_payment_transaction_reconcile
|
ON payment_transaction (status, last_reconciled_at);
|
END IF;
|
END //
|
DELIMITER ;
|
CALL add_payment_attempt_convergence_columns();
|
DROP PROCEDURE add_payment_attempt_convergence_columns;
|