Files
yms-daemon/internal/transaction/state.go
T
2026-08-17 10:10:14 +08:00

102 lines
3.8 KiB
Go

package transaction
import "fmt"
// State 服务端更新事务的持久化状态。
//
// 它刻画了一次单机更新从创建到提交的完整生命周期,以及回滚与失败两种异常
// 路径。状态转换遵循严格的前向顺序(见 forwardTransitions),非法转换会被
// TransitionError 拒绝,从而保证任何时刻事务都处于可解释、可恢复的确定位置。
type State string
const (
StateCreated State = "CREATED" // 事务已创建,等待校验。
StateValidating State = "VALIDATING" // 正在校验请求与前置条件。
StatePrepared State = "PREPARED" // 校验通过,准备启动。
StateStarting State = "STARTING" // 正在启动新实例。
StateSwitching State = "SWITCHING" // 正在切换流量。
StateVerifying State = "VERIFYING" // 正在验证切换结果。
StateDraining State = "DRAINING" // 正在排空旧实例。
StateCommitted State = "COMMITTED" // 更新已提交,终态。
StateRollingBack State = "ROLLING_BACK" // 正在回滚。
StateRolledBack State = "ROLLED_BACK" // 回滚完成,终态。
StateFailed State = "FAILED" // 不可恢复失败,终态。
)
// forwardTransitions 定义状态机正常推进路径上每一步的直接后继状态。
//
// 该映射只覆盖无异常的正常推进;回滚与失败属于特殊转换,由 CanTransitionTo
// 单独处理,不在此映射内。
var forwardTransitions = map[State]State{
StateCreated: StateValidating,
StateValidating: StatePrepared,
StatePrepared: StateStarting,
StateStarting: StateSwitching,
StateSwitching: StateVerifying,
StateVerifying: StateDraining,
StateDraining: StateCommitted,
}
// Valid 报告状态是否属于当前状态机协议。
//
// 返回 true 表示 s 是状态机认可的合法状态值,可用于转换校验与持久化判断;
// 返回 false 表示 s 不是本协议定义的状态。
func (s State) Valid() bool {
switch s {
case StateCreated,
StateValidating,
StatePrepared,
StateStarting,
StateSwitching,
StateVerifying,
StateDraining,
StateCommitted,
StateRollingBack,
StateRolledBack,
StateFailed:
return true
default:
return false
}
}
// Terminal 报告事务是否已经不可再推进。
//
// COMMITTED、ROLLED_BACK、FAILED 三个终态之后不再接受任何状态转换,事务的
// 生命周期到此结束,该判断是 CanTransitionTo 拒绝终态继续推进的依据。
func (s State) Terminal() bool {
return s == StateCommitted || s == StateRolledBack || s == StateFailed
}
// CanTransitionTo 校验正常推进、回滚和不可恢复失败三类转换。
//
// 该方法是状态机的核心规则:当前状态或目标状态非法、当前状态为终态时一律
// 拒绝;从 ROLLING_BACK 只允许到达 ROLLED_BACK 或 FAILED;其他非终态允许
// 进入 ROLLING_BACK 或 FAILED;其余情况必须严格遵循 forwardTransitions 定义
// 的前向路径。返回 true 表示转换被允许,false 表示拒绝。
func (s State) CanTransitionTo(next State) bool {
if !s.Valid() || !next.Valid() || s.Terminal() {
return false
}
if s == StateRollingBack {
return next == StateRolledBack || next == StateFailed
}
if next == StateRollingBack || next == StateFailed {
return true
}
return forwardTransitions[s] == next
}
// TransitionError 表示状态机拒绝了一次转换。
//
// 它记录了被拒绝转换的起点与终点状态,便于调用方识别非法推进并给出明确错误。
type TransitionError struct {
From State // 转换前的事务状态。
To State // 请求转换到的目标状态。
}
// Error 返回描述被拒绝转换的文本,格式为“起点 -> 终点”。
func (e *TransitionError) Error() string {
return fmt.Sprintf("transaction state transition is not allowed: %s -> %s", e.From, e.To)
}