Commit da91b91b by bergquist

transactions: start sessions and transactions at the same place

this make it possible for handler to use `withSession` when
transactions is not nedded and `inTransactionCtx` if its needed
without knowing who owns the session/transaction
parent 09e71e00
...@@ -22,21 +22,30 @@ func newSession() *DBSession { ...@@ -22,21 +22,30 @@ func newSession() *DBSession {
return &DBSession{Session: x.NewSession()} return &DBSession{Session: x.NewSession()}
} }
func startSession(ctx context.Context) *DBSession { func startSession(ctx context.Context, engine *xorm.Engine, beginTran bool) (*DBSession, error) {
value := ctx.Value(ContextSessionName) value := ctx.Value(ContextSessionName)
var sess *DBSession var sess *DBSession
sess, ok := value.(*DBSession) sess, ok := value.(*DBSession)
if !ok { if !ok {
newSess := newSession() newSess := &DBSession{Session: engine.NewSession()}
return newSess if beginTran {
err := newSess.Begin()
if err != nil {
return nil, err
}
}
return newSess, nil
} }
return sess return sess, nil
} }
func withDbSession(ctx context.Context, callback dbTransactionFunc) error { func withDbSession(ctx context.Context, callback dbTransactionFunc) error {
sess := startSession(ctx) sess, err := startSession(ctx, x, false)
if err != nil {
return err
}
return callback(sess) return callback(sess)
} }
......
...@@ -14,16 +14,16 @@ func (ss *SqlStore) InTransaction(ctx context.Context, fn func(ctx context.Conte ...@@ -14,16 +14,16 @@ func (ss *SqlStore) InTransaction(ctx context.Context, fn func(ctx context.Conte
} }
func (ss *SqlStore) inTransactionWithRetry(ctx context.Context, fn func(ctx context.Context) error, retry int) error { func (ss *SqlStore) inTransactionWithRetry(ctx context.Context, fn func(ctx context.Context) error, retry int) error {
sess := startSession(ctx) sess, err := startSession(ctx, ss.engine, true)
defer sess.Close() if err != nil {
if err := sess.Begin(); err != nil {
return err return err
} }
defer sess.Close()
withValue := context.WithValue(ctx, ContextSessionName, sess) withValue := context.WithValue(ctx, ContextSessionName, sess)
err := fn(withValue) err = fn(withValue)
// special handling of database locked errors for sqlite, then we can retry 3 times // special handling of database locked errors for sqlite, then we can retry 3 times
if sqlError, ok := err.(sqlite3.Error); ok && retry < 5 { if sqlError, ok := err.(sqlite3.Error); ok && retry < 5 {
...@@ -60,16 +60,13 @@ func inTransactionWithRetry(callback dbTransactionFunc, retry int) error { ...@@ -60,16 +60,13 @@ func inTransactionWithRetry(callback dbTransactionFunc, retry int) error {
} }
func inTransactionWithRetryCtx(ctx context.Context, callback dbTransactionFunc, retry int) error { func inTransactionWithRetryCtx(ctx context.Context, callback dbTransactionFunc, retry int) error {
var err error sess, err := startSession(ctx, x, true)
if err != nil {
sess := startSession(ctx)
defer sess.Close()
if err = sess.Begin(); err != nil {
return err return err
} }
defer sess.Close()
err = callback(sess) err = callback(sess)
// special handling of database locked errors for sqlite, then we can retry 3 times // special handling of database locked errors for sqlite, then we can retry 3 times
......
...@@ -5,7 +5,6 @@ import ( ...@@ -5,7 +5,6 @@ import (
"errors" "errors"
"testing" "testing"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
. "github.com/smartystreets/goconvey/convey" . "github.com/smartystreets/goconvey/convey"
...@@ -18,11 +17,9 @@ type testQuery struct { ...@@ -18,11 +17,9 @@ type testQuery struct {
var ProvokedError = errors.New("testing error.") var ProvokedError = errors.New("testing error.")
func TestTransaction(t *testing.T) { func TestTransaction(t *testing.T) {
InitTestDB(t) ss := InitTestDB(t)
Convey("InTransaction asdf asdf", t, func() { Convey("InTransaction asdf asdf", t, func() {
ss := SqlStore{log: log.New("test-logger")}
cmd := &models.AddApiKeyCommand{Key: "secret-key", Name: "key", OrgId: 1} cmd := &models.AddApiKeyCommand{Key: "secret-key", Name: "key", OrgId: 1}
err := AddApiKey(cmd) err := AddApiKey(cmd)
...@@ -50,7 +47,6 @@ func TestTransaction(t *testing.T) { ...@@ -50,7 +47,6 @@ func TestTransaction(t *testing.T) {
} }
return ProvokedError return ProvokedError
}) })
So(err, ShouldEqual, ProvokedError) So(err, ShouldEqual, ProvokedError)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment