diff --git a/transaction.go b/transaction.go new file mode 100644 index 00000000..5ede6301 --- /dev/null +++ b/transaction.go @@ -0,0 +1,26 @@ +// Copyright 2018 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +// AutoTransaction Execute sql wrapped in a transaction(abbr as tx), tx will automatic commit if no errors occurred +func AutoTransaction(f func(*Session) (interface{}, error), engine *Engine) (interface{}, error) { + session := engine.NewSession() + defer session.Close() + + if err := session.Begin(); err != nil { + return nil, err + } + + result, err := f(session) + if err != nil { + return nil, err + } + + if err := session.Commit(); err != nil { + return nil, err + } + + return result, nil +} diff --git a/transancation_test.go b/transancation_test.go new file mode 100644 index 00000000..13f3db1a --- /dev/null +++ b/transancation_test.go @@ -0,0 +1,52 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestAutoTransaction(t *testing.T) { + assert.NoError(t, prepareEngine()) + + type Test struct { + Id int64 `xorm:"autoincr pk"` + Msg string `xorm:"varchar(255)"` + Created time.Time `xorm:"created"` + } + + assert.NoError(t, testEngine.Sync2(new(Test))) + + engine := testEngine.(*Engine) + + // will success + AutoTransaction(func(session *Session) (interface{}, error) { + _, err := session.Insert(Test{Msg: "hi"}) + assert.NoError(t, err) + + return nil, nil + }, engine) + + has, err := engine.Exist(&Test{Msg: "hi"}) + assert.NoError(t, err) + assert.EqualValues(t, true, has) + + // will rollback + _, err = AutoTransaction(func(session *Session) (interface{}, error) { + _, err := session.Insert(Test{Msg: "hello"}) + assert.NoError(t, err) + + return nil, fmt.Errorf("rollback") + }, engine) + assert.Error(t, err) + + has, err = engine.Exist(&Test{Msg: "hello"}) + assert.NoError(t, err) + assert.EqualValues(t, false, has) +}