80 lines
1.9 KiB
Go
80 lines
1.9 KiB
Go
package transaction
|
|
|
|
import "fmt"
|
|
|
|
// State 是服务端更新事务的持久化状态。
|
|
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"
|
|
)
|
|
|
|
var forwardTransitions = map[State]State{
|
|
StateCreated: StateValidating,
|
|
StateValidating: StatePrepared,
|
|
StatePrepared: StateStarting,
|
|
StateStarting: StateSwitching,
|
|
StateSwitching: StateVerifying,
|
|
StateVerifying: StateDraining,
|
|
StateDraining: StateCommitted,
|
|
}
|
|
|
|
// Valid 报告状态是否属于当前状态机协议。
|
|
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 报告事务是否已经不可再推进。
|
|
func (s State) Terminal() bool {
|
|
return s == StateCommitted || s == StateRolledBack || s == StateFailed
|
|
}
|
|
|
|
// CanTransitionTo 校验正常推进、回滚和不可恢复失败三类转换。
|
|
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
|
|
}
|
|
|
|
func (e *TransitionError) Error() string {
|
|
return fmt.Sprintf("transaction state transition is not allowed: %s -> %s", e.From, e.To)
|
|
}
|