Skip to content
bitzorcas
中EN

Concept

Numbering 业务流水号引擎

源码校验 Numbering 的条件规则、六类分段、租户计数事实、断号补偿、业务表接续、CSV 种子、双 ORM 与当前商业边界。

Last updated

Numbering 实现了 Framework 的 ISequenceNumberGenerator,从三张租户化表选择规则、组装字符串并写入生成事实。它不生成数据库主键,也没有规则写入用例或管理后台;但它有一个只读治理查询入口(见 §12),供运营查看规则与计数事实。

1. 当前产品面

唯一冲突,最多 3 次

SequenceNumberRequest

选择条件规则

加载有序分段

计算非序号前缀

查询 GenerateRecord MAX

组装完整流水号

可选业务表判重

插入生成事实

模块本地除 Infrastructure 外,已有 Contracts 与 Application 项目用于暴露只读治理查询(见 §12)。公开 Port/纯算法在 BitzOrcas.Application.Numbering,API Host 通过 AddBitzOrcasNumberingPlatform() 注册实现。

2. 输入与输出

真实生成契约
// ① TableName + Field 是规则绑定键,不是任意动态 SQL 表名。
var request = new SequenceNumberRequest(
TableName: "DemoCase",
Field: "SerialId",
EntityValues: new Dictionary<string, object?>
{
["OfficeId"] = "SH",
["CaseType"] = "Civil"
},
IsEnabled: true,
ParentSequenceNumber: null,
BusinessSerialContext: null);
// ② 通过共享 Port 调用;结果同时返回字符串、数值和前缀。
Result<SequenceNumberResult> result =
await sequenceNumbers.GenerateAsync(request, cancellationToken);

请求没有 TenantId 字段,租户来自底层 IEntitySet<T> 的当前租户上下文。

3. 三张 owner 表

表责任
SysSequenceNumberRuleTableName/Field 下的条件、优先级、分隔符与补偿开关
SysSequenceNumberRuleSettingRuleId 下按 Sort 排列的分段
SysSequenceNumberGenerateRecord已分配字符串、数值、前缀、激活与父号事实

三者都继承 BizEntityBase,声明 IsTenant=true 和软删除。它们是规则/计数事实例外,不是恢复一表一 Entity/Mapper 模式的样板。

4. 规则选择

Generator 查询同 TableName/Field、IsActive && IsEnabled 的规则,按 Priority 升序交给 SequenceRuleSelector。条件支持 eq、ne、in、contains;字段从 EntityValues 读取。

空条件会在主循环中直接视为 true,因此它必须放在最大 Priority。否则它会提前吞掉后续条件规则。

5. 六种分段

SectionType输出
ConstantValue 常量
Date当前时间按 .NET 格式;可切固定四月财年逻辑
FiscalYear两位财年
BranchFieldSource 查 JSON 映射,失败回退 Value/FD
BusinessFieldEntityValues 字段,缺失回退 Value
SequenceNumber当前数值按 Length 左补零,默认 6 位

未知 SectionType 会被静默当 Constant,而不是返回配置错误。

6. 当前交付规则

种子只有两个演示规则:

  • DemoCase.SerialId → CASE-{yy}-{seq6};
  • DemoInvoice.SerialId → INV-{yyyy}-{seq6}。

两条规则和六条设置都写入 TenantId 1000001。它们是示例基线,不是面向任意业务表自动生效的通用规则。

7. 计数与前缀

前缀是所有非 SequenceNumber 段按 Separator 拼接的字符串。例如 CASE-26。Generator 按 Tenant + TableName + Field + Prefix 查询所有事实的最大 SequenceNumber,再加一。

Prefix 变化自然形成新计数区间,所以 Date/FiscalYear/Branch/BusinessField 都可能触发“重置”。源码没有独立的日/月/年 reset policy 字段。

8. 唯一性边界

数据库唯一索引是 TenantId + TableName + Field + SequenceNumberStr。两个并发调用可能同时读到同一个 MAX;一个插入成功,另一个依靠数据库异常字符串识别冲突并重试。

异常识别只匹配若干英文文本和 SQL Server 编号,属于脆弱的 provider 兼容层;非匹配异常会直接抛出。

9. 业务表接续

可选 IBusinessSerialContext 解决两类迁移问题:事实表为空时从业务表 MAX 接续;生成后检查完整字符串是否已存在。

该回调由业务 owner 实现,Numbering 不拼接动态表名 SQL。当前源码仓库没有生产业务模块调用 ISequenceNumberGenerator 的证据,主要消费证据来自测试。

10. 断号补偿

规则 IsCompensate=true 时,第一次尝试优先查同前缀、IsActivated=false 的最小数值,把它更新为请求的激活状态并返回。找不到跳号不会让生成失败,而是继续分配新号。

补偿路径不调用业务表 ExistsInBusinessTableAsync,也没有并发 claim 条件;两个调用可能读到同一未激活行。

11. 当前保证与不保证

可以依赖不可假设
三张租户/软删元数据表已有管理 API、权限或审计
条件规则与六类分段算法Feature 已在 GenerateAsync 强制
双 ORM IEntitySet 实现数据库原子 increment/分布式锁
字符串唯一索引兜底StartValue 已生效
可选业务表接续/判重补偿是并发安全 claim
三次唯一冲突重试所有 provider 异常都可识别

12. 治理查询入口

GET /api/numbering/rules(资源 numbering/rules、动作 Read)是一个 owner-local 只读治理报告。查询参数:Search(可选)、Status(可选,取值 all/active/inactive/conditional,默认 all)。

返回 NumberingGovernanceReport:

  • Rules:最多 200 条规则摘要(超出置 Truncated=true),每条 NumberingRuleSummary 给出 RuleKey(形如 {Table}-{Field}-{RuleName})、Compensate、Conditional、Condition(受控,不含运行时业务值)、Priority、ConditionScope,以及人读 Template(如 {date:yyyyMMdd}、{fiscalYear}、{branch}、{field:...}、{seq:n})和每段详情(Segments,含 SubstitutionConfigured 标志,替换体本身不返回);
  • 全局计数:TotalRules、ActiveRules、ConditionalRules、CompensatingRules;
  • 计数事实:GeneratedRecords、ActivatedRecords、HeldRecords(已生成但未激活);
  • GeneratedAt。

读存储 NumberingGovernanceReadStore 在 Infrastructure 层实现 INumberingGovernanceReadStore,刻意只返回能力统计与规则模板,不返回已生成的业务流水号、父级流水号或分支映射体。未注册时降级为 fail-closed 的 UnavailableNumberingGovernanceReadStore。错误码:Numbering.Governance.StoreUnavailable(ServiceUnavailable)、Numbering.Governance.InvalidQuery(Validation)。

与 MasterData 治理查询同属一类 owner-local 只读投影:回答”有哪些规则、生成了多少”,不回答”规则是否正确、序列是否无重复”。

13. 文档导航

14. 源码核查

Terminal window
# Generator、规则选择与分段算法。
rg -n "GenerateAsync|SelectRule|AssembleFull" src/Platform/Numbering src/Framework/BitzOrcas.Application/Numbering -g '*.cs'
# 治理查询入口与只读报告。
rg -n "GetNumberingGovernance|NumberingGovernanceReport|NumberingGovernanceReadStore" \
src/Platform/Numbering -g '*.cs'
# 当前生产消费面;除注册外应无业务调用。
rg -n "ISequenceNumberGenerator|SequenceNumberRequest" src -g '*.cs' --glob '!**/bin/**' --glob '!**/obj/**'

返回平台模块目录 · 持久化构建块

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%