diff --git a/transactor.go b/transactor.go index 6087bfa..e623831 100644 --- a/transactor.go +++ b/transactor.go @@ -1,6 +1,7 @@ package oniontx import ( + "container/list" "context" "errors" "fmt" @@ -54,17 +55,45 @@ func NewTransactor[B TxBeginner[T, O], T Tx, O any]( // WithinTx execute all queries with Tx. // The function create new Tx or reuse Tx obtained from context.Context. +// +// The behavior described on WithinTxWithOpts function's docs. func (t *Transactor[B, T, O]) WithinTx(ctx context.Context, fn func(ctx context.Context) error) (err error) { return t.WithinTxWithOpts(ctx, fn) } // WithinTxWithOpts execute all queries with Tx and transaction Options. // The function create new Tx or reuse Tx obtained from context.Context. +/* +When WithinTxWithOpts call recursively, the highest level function responsible for applying commit or rollback of a transaction. + + tr := NewTransactor[...](...) + err := tr.WithinTx(ctx, func(ctx context.Context) error { // commit/rollback execute on this level + // some logic + + err := tr.WithinTx(ctx, func(ctx context.Context) error { + // some logic + }) + + err = tr.WithinTx(ctx, func(ctx context.Context) error { + // some logic + }) + // some logic + }) + +Note: + ++ a processed error returns to the highest level function for commit or rollback. + ++ panics are transformed to errors with the same messages. + ++ higher level panics override lower level panics. +*/ func (t *Transactor[B, T, O]) WithinTxWithOpts(ctx context.Context, fn func(ctx context.Context) error, opts ...Option[O]) (err error) { var ( nilBeginner B nilOperator СtxOperator[T] = nil ) + list.New() if t.beginner == nilBeginner { return fmt.Errorf("transactor - can't begin: %w", ErrNilTxBeginner) }