知识全景图/ 软件工程与系统/ 如何设计业务数据库/ 周期账单与定时任务

如何设计数据库周期账单与定时任务

cron 不是业务规则。定时任务只是把“应生成的一期”变成事实。

这页只讲一件事:每月房租为什么不会生成两次,也不会漏生成。

一、先看事故
事故根因设计动作
每月房租生成两次。任务超时重试,第一次其实已写入。同一规则同一期必须有唯一 occurrence_key
任务停三天,不知道补哪些。只有 next_run_at,没有“应生成实例”。先生成 occurrences,再补跑。
规则改金额后旧账解释不了。账目没有规则版本快照。每一期保存生成时的规则版本。
每月 31 日在 2 月生成错。用固定秒数代替业务日历。规则保存时区和月底策略。
分期提前结清后仍继续生成。未来计划和已发生事实混在一起。分期计划、应生成实例、真实账目分开。
判断:规则不是账目,任务不是事实。真正入账前,先有可审计的“本期应生成”。
二、建表前只问 5 个问题
问题最低设计
用户的长期意图是什么?recurring_rules 保存金额、账户、分类、周期、状态。
某一期是否应该生成?recurring_occurrences 保存应生成实例。
同一期怎样防重复?UNIQUE(rule_id, occurrence_key)
本期按哪版规则生成?occurrence 保存规则版本快照。
任务跑完怎么证明?任务记录、生成数量、失败数量、派生对账。
三、最小模型
recurring_rules: rule_id, ledger_id, amount_cents, account_id, category_id recurrence_type, timezone, calendar_policy, status, version recurring_occurrences: occurrence_id, rule_id, occurrence_key, due_on status, generated_entry_id, rule_version_snapshot scheduled_job_runs: job_run_id, job_name, started_at, finished_at status, generated_count, failed_count, checkpoint
四、验收规则
样本通过标准
任务超时重试。同一期只生成一条账。
任务停三天。补跑候选清单准确,不靠猜。
每月 31 日规则。2 月、闰年、大小月按业务策略生成。
规则改金额。旧期、新期都能解释。
分期提前结清。未来期不再生成,历史账目不被删。
五、下一步
任务重试
继续看幂等键、唯一约束和失败重试。
暂停和取消
继续看状态机和合法迁移。
已重或已漏
继续看候选清单、dry-run 和批量修复。
记住:任务可以重复执行,事实不能重复产生。唯一键守住同一期,occurrence 守住补跑边界。