f536987a7e
- doc: add comment
102 lines
3.8 KiB
Go
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)
|
|
}
|