- settlement(1.1): exhibition_revenue_records 加 UNIQUE(exhibition_id,cycle_start_time) + CreateRevenueRecord ON CONFLICT DO NOTHING; MQ 用 settled_at 替代复用 is_processed; 恢复扫描器过滤改 settled_at IS NULL; created_at 统一毫秒; 删死代码 cleanup_worker.go。 - hours(1.2): 新增 exhibition_hours_log/asset_exhibition_hours_log(source_id 唯一)幂等表; fan_profile/assetLevel 的 AddExhibitionHours 按 sourceID 幂等(事务包裹); 存量重算脚本。 - mint(1.4/1.5/1.6): crystal_transaction_records (source_id,change_type) 部分唯一索引 + UpdateCrystalBalance/CreateMintOrder 幂等; 保底改 crypto/rand; 下线伪 tx_hash; doMint Redis Lua 原子限流。 - migrations 001/002/003; 各服务单测(自包含, 缺 DB t.Skip)。 Co-Authored-By: Claude <noreply@anthropic.com>
46 lines
2.2 KiB
PL/PgSQL
46 lines
2.2 KiB
PL/PgSQL
-- 2026_07_21_003_exhibition_hours_idempotent.sql
|
||
-- 批次1.2:累计时长幂等(用户级 + 资产级)
|
||
-- 执行前请先备份:
|
||
-- pg_dump -h <host> -U postgres -t exhibition_hours_log -t asset_exhibition_hours_log <db> > backup_1_2.sql
|
||
-- 触发场景:fan_profile_repository.AddExhibitionHours/assetLevelService.AddExhibitionHours
|
||
-- 重复调用会造成 total_exhibition_hours / season_exhibition_hours 多次叠加
|
||
-- 设计:每条幂等键由 source_id 唯一约束保证,INSERT ON CONFLICT DO NOTHING 即跳过
|
||
|
||
BEGIN;
|
||
|
||
-- (1) 用户级幂等 log
|
||
CREATE TABLE IF NOT EXISTS exhibition_hours_log (
|
||
id BIGINT PRIMARY KEY,
|
||
source_id VARCHAR(100) NOT NULL UNIQUE,
|
||
user_id BIGINT NOT NULL,
|
||
star_id BIGINT NOT NULL,
|
||
hours BIGINT NOT NULL,
|
||
created_at BIGINT NOT NULL
|
||
);
|
||
CREATE INDEX IF NOT EXISTS ix_exh_log_user_star
|
||
ON exhibition_hours_log (user_id, star_id);
|
||
CREATE INDEX IF NOT EXISTS ix_exh_log_created
|
||
ON exhibition_hours_log (created_at);
|
||
|
||
-- (2) 资产级幂等 log
|
||
CREATE TABLE IF NOT EXISTS asset_exhibition_hours_log (
|
||
id BIGINT PRIMARY KEY,
|
||
source_id VARCHAR(100) NOT NULL UNIQUE,
|
||
asset_id BIGINT NOT NULL,
|
||
hours INT NOT NULL,
|
||
created_at BIGINT NOT NULL
|
||
);
|
||
CREATE INDEX IF NOT EXISTS ix_asset_exh_log_asset
|
||
ON asset_exhibition_hours_log (asset_id);
|
||
|
||
-- (3) 序列同步(CLAUDE.md 强制;新表无现存行,序列置 1)
|
||
-- 内部去重 log 表无脚本硬编码其 id,不适用 START 10000 约定;序列从 1 起步。
|
||
CREATE SEQUENCE IF NOT EXISTS exhibition_hours_log_id_seq OWNED BY exhibition_hours_log.id;
|
||
ALTER TABLE exhibition_hours_log ALTER COLUMN id SET DEFAULT nextval('exhibition_hours_log_id_seq');
|
||
SELECT setval('exhibition_hours_log_id_seq', GREATEST((SELECT COALESCE(MAX(id),0) FROM exhibition_hours_log), 1));
|
||
CREATE SEQUENCE IF NOT EXISTS asset_exhibition_hours_log_id_seq OWNED BY asset_exhibition_hours_log.id;
|
||
ALTER TABLE asset_exhibition_hours_log ALTER COLUMN id SET DEFAULT nextval('asset_exhibition_hours_log_id_seq');
|
||
SELECT setval('asset_exhibition_hours_log_id_seq', GREATEST((SELECT COALESCE(MAX(id),0) FROM asset_exhibition_hours_log), 1));
|
||
|
||
COMMIT;
|