// Package transaction 实现服务端更新请求的事务状态机与持久化层。 // // 该包负责把一次单机更新请求建模为一个持久化的事务记录,并通过严格的 // 状态机约束其生命周期:从 CREATED 一路推进到 COMMITTED,或进入 // ROLLING_BACK/ROLLED_BACK/FAILED 等终态。事务的执行遵循“先记录意图、 // 再执行外部副作用、最后 inspect 核对”的协议,以保证进程崩溃后能够安全恢复。 // // 包内数据统一存储在单个本地 SQLite 数据库中(见 store.go),Coordinator // 负责在进程内串行化执行并驱动外部步骤,其余类型则定义了贯穿全局的数据模型、 // 状态、事件与错误约定。 package transaction import ( "encoding/json" "time" ) // Transaction 一次更新请求的服务端持久化快照。 // // 它同时承担幂等控制与状态推进两个职责:IdempotencyKey 唯一标识一次客户端 // 重试,Version 用于乐观锁防止并发覆盖,State 记录当前状态机位置。除终态外, // 数据库中同时最多只允许存在一条未结束的事务(由单活动事务索引保证)。 type Transaction struct { ID string // 事务唯一标识,为空时由存储层自动生成。 IdempotencyKey string // 幂等键,重复请求据此返回同一事务。 Source string // 请求来源,如 ymsctl 或守护进程。 Service string // 目标服务名,如 backend。 Request json.RawMessage // 原始请求载荷,仅作快照保存。 State State // 当前状态机状态。 Version int64 // 乐观锁版本号,每次状态变化自增。 CreatedAt time.Time // 事务首次创建时间(UTC)。 UpdatedAt time.Time // 最近一次变更时间(UTC)。 } // ListFilter ymsctl list 命令查询历史记录时使用的过滤条件。 // // 所有字段均按精确值匹配,服务端不会对过滤条件做任何推断或模糊处理。 type ListFilter struct { Limit int // 最多返回的记录条数,必须在 1 到 1000 之间。 Service string // 按服务名精确过滤,为空表示不过滤。 State State // 按状态精确过滤,为空表示不过滤。 } // CreateRequest 包含创建事务所需的不可变请求信息。 // // 该结构体是 CreateTransaction 的入参,其中的 Request 必须是合法的 JSON, // 否则创建会被拒绝;空请求会被规范化为空对象 {}。 type CreateRequest struct { ID string // 事务唯一标识,允许留空由存储层生成。 IdempotencyKey string // 幂等键,必填且不能为空白。 Source string // 请求来源,必填且不能为空白。 Service string // 目标服务名,必填且不能为空白。 Request json.RawMessage // 原始请求载荷,必须是合法 JSON。 } // StepStatus 外部步骤的持久化执行状态。 // // 它描述了单个外部副作用在“记录意图 -> 执行 -> 核对”协议中所处的阶段, // 只有 SUCCEEDED 与 FAILED 是最终状态,INTENT_RECORDED 表示仍需执行或核对。 type StepStatus string const ( StepIntentRecorded StepStatus = "INTENT_RECORDED" // 已记录意图,尚未确定最终结果。 StepSucceeded StepStatus = "SUCCEEDED" // 外部副作用已确认成功发生。 StepFailed StepStatus = "FAILED" // 外部副作用已确认未成功发生。 ) // Step 记录一次外部副作用的意图和最终核对结果。 // // 一条步骤在事务生命周期内由 step_key 唯一标识,意图(Intent)在副作用执行前 // 必须已经落库,结果(Result)则在 inspect 核对后写入,用于崩溃恢复时判断 // 副作用是否真实发生,从而避免重复执行或丢失执行。 type Step struct { TransactionID string // 所属事务的 ID。 Key string // 步骤在事务内的唯一键。 Name string // 步骤的语义名称,用于日志与事件展示。 Status StepStatus // 步骤当前状态。 Intent json.RawMessage // 执行前持久化的意图载荷。 Result json.RawMessage // 核对后持久化的结果载荷,可为空。 Error string // 步骤失败时的错误信息,成功时为空字符串。 CreatedAt time.Time // 步骤意图首次记录时间(UTC)。 UpdatedAt time.Time // 步骤最近一次变更时间(UTC)。 } // StepIntent 执行外部操作前必须先持久化的内容。 // // 它描述了将要执行的外部副作用,只有先把它成功写入数据库,Coordinator 才会 // 真正调用 Operation.Apply,从而保证任何时刻都能回答“这一步是否已执行过”。 type StepIntent struct { Key string // 步骤在事务内的唯一键,用于去重与恢复定位。 Name string // 步骤的语义名称。 Intent json.RawMessage // 执行该步骤所需的参数载荷。 } // Event 供查询和 WSS 断联恢复使用的顺序事件。 // // 每个事务状态变化或步骤意图/结果变化都会追加一条有序事件,Sequence 在事务 // 内单调递增。客户端据此实现断线后的增量拉取(EventsAfter),重放遗漏的事件。 type Event struct { Sequence int64 // 全局递增的事件顺序号。 TransactionID string // 事件所属事务的 ID。 StepKey string // 关联的步骤键,事务级事件为空字符串。 Kind string // 事件类型,如 TRANSACTION_CREATED、STEP_SUCCEEDED。 FromState State // 变化前的状态,非状态类事件为空。 ToState State // 变化后的状态,非状态类事件为空。 Message string // 附加的人类可读信息。 CreatedAt time.Time // 事件产生时间(UTC)。 }