mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
SQLStore: Add test for nested transactions events (#60500)
* SQLStore: Add test for nested transactions events * Replace fmt.Print* with t.Log* * Add different test cases
This commit is contained in:
parent
4def287e62
commit
2b0de82aa9
@ -68,7 +68,7 @@ func startSessionOrUseExisting(ctx context.Context, engine *xorm.Engine, beginTr
|
||||
|
||||
// WithDbSession calls the callback with the session in the context (if exists).
|
||||
// Otherwise it creates a new one that is closed upon completion.
|
||||
// A session is stored in the context if sqlstore.InTransaction() has been been previously called with the same context (and it's not committed/rolledback yet).
|
||||
// A session is stored in the context if sqlstore.InTransaction() has been previously called with the same context (and it's not committed/rolledback yet).
|
||||
// In case of sqlite3.ErrLocked or sqlite3.ErrBusy failure it will be retried at most five times before giving up.
|
||||
func (ss *SQLStore) WithDbSession(ctx context.Context, callback DBTransactionFunc) error {
|
||||
return ss.withDbSession(ctx, ss.engine, callback)
|
||||
|
@ -85,11 +85,9 @@ func (ss *SQLStore) inTransactionWithRetryCtx(ctx context.Context, engine *xorm.
|
||||
return err
|
||||
}
|
||||
|
||||
if len(sess.events) > 0 {
|
||||
for _, e := range sess.events {
|
||||
if err = bus.Publish(ctx, e); err != nil {
|
||||
ctxLogger.Error("Failed to publish event after commit.", "error", err)
|
||||
}
|
||||
for _, e := range sess.events {
|
||||
if err = bus.Publish(ctx, e); err != nil {
|
||||
ctxLogger.Error("Failed to publish event after commit.", "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,10 @@ package sqlstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@ -65,3 +67,75 @@ func TestIntegrationReuseSessionWithTransaction(t *testing.T) {
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntegrationPublishAfterCommitWithNestedTransactions(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test")
|
||||
}
|
||||
|
||||
ss := InitTestDB(t)
|
||||
ctx := context.Background()
|
||||
|
||||
// On X success
|
||||
var xHasSucceeded bool
|
||||
ss.Bus().AddEventListener(func(ctx context.Context, e *X) error {
|
||||
xHasSucceeded = true
|
||||
t.Logf("Succeeded and committed: %T\n", e)
|
||||
return nil
|
||||
})
|
||||
|
||||
// On Y success
|
||||
var yHasSucceeded bool
|
||||
ss.Bus().AddEventListener(func(ctx context.Context, e *Y) error {
|
||||
yHasSucceeded = true
|
||||
t.Logf("Succeeded and committed: %T\n", e)
|
||||
return nil
|
||||
})
|
||||
|
||||
t.Run("When no session is stored into the context, each transaction should be independent", func(t *testing.T) {
|
||||
t.Cleanup(func() { xHasSucceeded = false; yHasSucceeded = false })
|
||||
|
||||
err := ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
|
||||
t.Logf("Outer transaction: doing X... success!")
|
||||
sess.PublishAfterCommit(&X{})
|
||||
|
||||
require.NoError(t, ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
|
||||
t.Log("Inner transaction: doing Y... success!")
|
||||
sess.PublishAfterCommit(&Y{})
|
||||
return nil
|
||||
}))
|
||||
|
||||
t.Log("Outer transaction: doing Z... failure, rolling back...")
|
||||
return errors.New("z failed")
|
||||
})
|
||||
|
||||
assert.NotNil(t, err)
|
||||
assert.False(t, xHasSucceeded)
|
||||
assert.True(t, yHasSucceeded)
|
||||
})
|
||||
|
||||
t.Run("When the session is stored into the context, the inner transaction should depend on the outer one", func(t *testing.T) {
|
||||
t.Cleanup(func() { xHasSucceeded = false; yHasSucceeded = false })
|
||||
|
||||
err := ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
|
||||
t.Logf("Outer transaction: doing X... success!")
|
||||
sess.PublishAfterCommit(&X{})
|
||||
|
||||
require.NoError(t, ss.InTransaction(ctx, func(ctx context.Context) error {
|
||||
t.Log("Inner transaction: doing Y... success!")
|
||||
sess.PublishAfterCommit(&Y{})
|
||||
return nil
|
||||
}))
|
||||
|
||||
t.Log("Outer transaction: doing Z... failure, rolling back...")
|
||||
return errors.New("z failed")
|
||||
})
|
||||
|
||||
assert.NotNil(t, err)
|
||||
assert.False(t, xHasSucceeded)
|
||||
assert.False(t, yHasSucceeded)
|
||||
})
|
||||
}
|
||||
|
||||
type X struct{}
|
||||
type Y struct{}
|
||||
|
Loading…
Reference in New Issue
Block a user