yeg
2026-09-17 1805a7b9648ff9cfbd19129255a5a4fa62f0261e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
-- 编号让位(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;