Skip to content

Commit

Permalink
propagating context to gorm transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavel Rybintsev committed Dec 10, 2020
1 parent ffd15a2 commit cf019fb
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
16 changes: 12 additions & 4 deletions gorm/transaction.go
Expand Up @@ -69,7 +69,7 @@ func BeginFromContext(ctx context.Context) (*gorm.DB, error) {
if txn.parent == nil {
return nil, ErrCtxTxnNoDB
}
db := txn.Begin()
db := txn.beginWithContext(ctx)
if db.Error != nil {
return nil, db.Error
}
Expand All @@ -89,7 +89,7 @@ func BeginWithOptionsFromContext(ctx context.Context, opts *sql.TxOptions) (*gor
if txn.parent == nil {
return nil, ErrCtxTxnNoDB
}
db := txn.BeginWithOptions(opts)
db := txn.beginWithContextAndOptions(ctx, opts)
if db.Error != nil {
return nil, db.Error
}
Expand All @@ -99,11 +99,15 @@ func BeginWithOptionsFromContext(ctx context.Context, opts *sql.TxOptions) (*gor
// Begin starts new transaction by calling `*gorm.DB.Begin()`
// Returns new instance of `*gorm.DB` (error can be checked by `*gorm.DB.Error`)
func (t *Transaction) Begin() *gorm.DB {
return t.beginWithContext(context.Background())
}

func (t *Transaction) beginWithContext(ctx context.Context) *gorm.DB {
t.mu.Lock()
defer t.mu.Unlock()

if t.current == nil {
t.current = t.parent.Begin()
t.current = t.parent.BeginTx(ctx, nil)
}

return t.current
Expand All @@ -112,11 +116,15 @@ func (t *Transaction) Begin() *gorm.DB {
// BeginWithOptions starts new transaction by calling `*gorm.DB.BeginTx()`
// Returns new instance of `*gorm.DB` (error can be checked by `*gorm.DB.Error`)
func (t *Transaction) BeginWithOptions(opts *sql.TxOptions) *gorm.DB {
return t.beginWithContextAndOptions(context.Background(), opts)
}

func (t *Transaction) beginWithContextAndOptions(ctx context.Context, opts *sql.TxOptions) *gorm.DB {
t.mu.Lock()
defer t.mu.Unlock()

if t.current == nil {
t.current = t.parent.BeginTx(context.Background(), opts)
t.current = t.parent.BeginTx(ctx, opts)
}

return t.current
Expand Down
20 changes: 18 additions & 2 deletions gorm/transaction_test.go
Expand Up @@ -367,8 +367,9 @@ func TestBeginFromContext_Good(t *testing.T) {

func TestBeginFromContext_Bad(t *testing.T) {
tests := []struct {
desc string
withOpts bool
desc string
withOpts bool
contextCanceled bool
}{
{
desc: "begin without options",
Expand All @@ -378,11 +379,26 @@ func TestBeginFromContext_Bad(t *testing.T) {
desc: "begin with options",
withOpts: true,
},
{
desc: "canceled context without context",
withOpts: true,
contextCanceled: true,
},
{
desc: "canceled context with options",
withOpts: false,
contextCanceled: true,
},
}
for _, test := range tests {
test := test
t.Run(test.desc, func(t *testing.T) {
ctx := context.Background()
if test.contextCanceled {
var cancel context.CancelFunc
ctx, cancel = context.WithCancel(ctx)
cancel()
}

// Case: Transaction missing from context
txn1, err := beginFromContext(ctx, test.withOpts)
Expand Down

0 comments on commit cf019fb

Please sign in to comment.