参考
名词释义
go-sequent 常用名词:Projector、SyncInTxn、Aggregate、Command、Event、EventStore、hash chain、UnitOfWork、OCC、Idempotency、Tenant、Outbox、Snapshot、Tombstone。
名词释义
下面这些词和 go-sequent 当前行为、以及锁定决策一致。框架与 API 名称保留英文,括号里是中文读者好懂的说法。
A–C
Aggregate / AggregateRoot(聚合 / 聚合根)
一次业务变更里「必须一起对上」的边界。嵌入 aggregate.Base,状态只在 applier 里改;Command 方法校验通过后调用 Apply。通过 Repository 与 UnitOfWork 加载、提交,不要跨 goroutine 共用同一个实例。见 AggregateRoot。
AfterCommit(提交成功后的钩子)
用 workflow.RegisterAfterCommit 注册。只有事务提交成功之后才会跑,适合发通知这类「离开数据库」的副作用。钩子失败不会把已经提交的事件撤销。见 Workflow。
AuthZ(授权)
在 Command 入口做权限判断:实现 security.Authorizer,用 WithAuthorizer 装上。拒绝时返回 ErrDenied。这和登录认证(AuthN)是两件事。EventStore 靠 hash chain 发现篡改,没有事件签名。见 AuthZ。
Command(命令)
「我想改系统」的意图:有 CommandType、可选的 AggregateID 与 Meta,可以实现 Validate。经 CommandService.Execute 进入,依次走过中间件、AuthZ、Handler。见 Command。
Compensating event(补偿事件)
追加一条新的领域事件,用来抵消或修正以前的事实,而不是改历史记录。业务更正会用到;配合 Tombstone,也可以在读模型里做 GDPR 式的清除。
E–H
Event(事件)
已经发生的事实(过去时),带类型名和信封信息(聚合 id、序号、时间)。入库后驱动 Projector 与 Workflow;解码走 event.Registry。见 Event。
EventStore(事件库)
持久化 Command 记录和每个聚合的事件流:强制 OCC 与 Unique keys,并按聚合维护 hash chain。实现有 memory 与 postgres。业务代码一般通过 Repository 用它,很少直接摸底层。见 EventStore。
Hash chain(哈希链)
用来发现「事件有没有被改过」。每个事件存 prev_hash 与 event_hash(对规范字段做 SHA-256,公式在 eventstore/hashchain)。链按单个聚合的事件流走,起点 prev_hash 是 32 个零字节。加载时和 VerifyChain 会校验。能发现篡改,但不是事件签名,追加和加载都会多一点开销。
L–M
Ledger 读模型(账本用余额表等)
余额、账本这类查询用表。它们在写事务里由 Projector 更新(SyncInTxn),所以提交返回后立刻能读到自己刚写的数据。bank 示例里的 BalanceProjector 是内存演示;生产请用 SQL 持久化。见 Projector。
Meta(命令元数据)
command.Meta:CommandID、TenantID、UserID、IdempotencyKey、关联 / 因果 id、Source、AuthContext 等。AuditOf 可生成审计快照。
Money(decimal 金额)
types.Money:decimal 数额 + 币种。JSON 里数额是字符串。禁用 float64。见 Money。
O–P
obs / OpenTelemetry
可选的写路径遥测:延迟、结果、OCC 冲突、可选的 outbox 深度。不是业务审计来源;Provider 由应用自己接。见 OpenTelemetry。
OCC
乐观并发控制:用 ExpectedVersion 防并发写冲突。追加时要求它等于流末尾,否则返回 ErrOptimisticConcurrency。obs 可以统计冲突是否暴增。见 Unique keys 与 OCC 与 写路径一致性。
Outbox
和事件在同一事务里写入的「待投递」行,再由轮询 Postgres 表异步发出去。账本类读模型仍走 SyncInTxn;Outbox 留给异步和外部副作用。见 Publisher。
partition_key(分区键)
聚合 / 事件流上的分区提示,通常来自 tenancy.PartitionKey,方便在共享 schema 里做物理分区或收窄 Unique key 范围。不是「每个租户一个 schema」。见 分区。
Projector(读模型更新器)
实现 publish.Handler(可带 ManagedTables),负责把事件写成查询用读模型——例如余额表。注册在 SyncInTxn 上:Append 之后、提交之前调用;失败会回滚整次写入。重建读模型时用 PublishProjectorsOnly,会跳过 Workflow。见 Projector。
文档里如果说「投影」,指的就是这类读模型更新;正文尽量用 Projector / 读模型,避免干巴巴的「投影」一词。
R–S
Read-your-writes(提交后立刻可读)
一次写入成功返回后,同一个客户端马上能读到这次更新。账本靠 SyncInTxn:余额表和事件在同一事务里改完,再提交返回。
Snapshot(快照)
把聚合状态折成一份 JSON,加载时「快照 + 之后的事件」即可,少重放整段历史。snapshot.Snapshotter 可在后台批量生成。见 Snapshotting。
SyncInTxn
发布模式:在写事务里同步更新读模型——先跑 Projector,再跑 Workflow。账本 / 余额类读模型必须用它。见 Publisher。
T–W
Tenant vs User(租户与用户)
Meta.TenantID 是多租户隔离单元(例如入驻商户);Meta.UserID 是操作者(买家、运营)。不要只信客户端传来的 UserID,应结合 AuthContext 与 AuthZ。tenancy 中间件可以把租户从 context 拷进 Meta。不要给每个终端用户单独发一个 TenantID。见 Tenancy(多租户)。
Tombstone(标记清除事件)
GDPR 做法:追加类似 gdpr.SubjectTombstoned 的标记事件,由 Projector 清空或不再提供个人数据。产品路径不是 crypto-shredding(用毁钥让密文永远解不开)。口语里的「墓碑」指的就是这类标记事件。
Unique keys(业务唯一键)
UniqueKeys 是 scope → value 映射,例如带租户前缀的 owner。数据库唯一冲突会变成 ErrUniqueKeyViolation。见 Unique keys 与 OCC。
Idempotency
同一业务键重复提交只生效一次。键空间是 (TenantID, IdempotencyKey);成功后的重试默认当空操作(Strict 模式返回 ErrReplay)。存储有 memory 与 postgres。见 Idempotency。
UnitOfWork(挂在 context 上的工作单元)
每次 Execute 一个、挂在 context 上的 identity map。Add / Load 复用同一聚合实例,Commit 按加载顺序收集未提交事件。不要跨 goroutine 共享。见 Repository。
Upcaster
加载时把旧事件载荷转成新形状(event/upcast)。不是用来导入 Ruby Sequent 数据库的工具。见 事件演进。
Workflow
用 RegisterWorkflow 注册的事件编排处理器。在 SyncInTxn 上跑,但不参与读模型重建;可以注册 AfterCommit 钩子。见 Workflow。
文档随 go-sequent 源码更新;若与 API 不一致,以源码为准。