package controller import ( "context" "sync" ) type hTransactionKey struct{} type HandlerTransaction struct { context.Context lock sync.Mutex parent context.Context todo []func() } func (h *HandlerTransaction) do(f func()) { if h == nil { f() return } h.lock.Lock() defer h.lock.Unlock() h.todo = append(h.todo, f) } func (h *HandlerTransaction) Commit() { h.lock.Lock() fs := h.todo h.todo = nil h.lock.Unlock() for _, f := range fs { f() } } func (h *HandlerTransaction) Rollback() { h.lock.Lock() h.todo = nil h.lock.Unlock() } func NewHandlerTransaction(ctx context.Context) *HandlerTransaction { ht := &HandlerTransaction{ parent: ctx, } ctx = context.WithValue(ctx, hTransactionKey{}, ht) ht.Context = ctx return ht } func getHandlerTransaction(ctx context.Context) *HandlerTransaction { v, _ := ctx.Value(hTransactionKey{}).(*HandlerTransaction) return v }