From eb27fffacfb41317bafc621c13a7ebe31ce1a465 Mon Sep 17 00:00:00 2001 From: BetaCat Date: Mon, 17 Sep 2018 22:45:49 +0800 Subject: [PATCH] enhancement: auto-transaction (#1093) * enhancement: auto-transaction * auto transaction --- .gitignore | 1 + transaction.go | 26 ++++++++++++++++++++++ transancation_test.go | 52 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 transaction.go create mode 100644 transancation_test.go diff --git a/.gitignore b/.gitignore index 22486d5f..f1757b98 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,6 @@ temp_test.go .vscode xorm.test *.sqlite3 +test.db.sql .idea/ diff --git a/transaction.go b/transaction.go new file mode 100644 index 00000000..4104103f --- /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 + +// Transaction Execute sql wrapped in a transaction(abbr as tx), tx will automatic commit if no errors occurred +func (engine *Engine) Transaction(f func(*Session) (interface{}, error)) (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..b9a89878 --- /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 TestTx struct { + Id int64 `xorm:"autoincr pk"` + Msg string `xorm:"varchar(255)"` + Created time.Time `xorm:"created"` + } + + assert.NoError(t, testEngine.Sync2(new(TestTx))) + + engine := testEngine.(*Engine) + + // will success + engine.Transaction(func(session *Session) (interface{}, error) { + _, err := session.Insert(TestTx{Msg: "hi"}) + assert.NoError(t, err) + + return nil, nil + }) + + has, err := engine.Exist(&TestTx{Msg: "hi"}) + assert.NoError(t, err) + assert.EqualValues(t, true, has) + + // will rollback + _, err = engine.Transaction(func(session *Session) (interface{}, error) { + _, err := session.Insert(TestTx{Msg: "hello"}) + assert.NoError(t, err) + + return nil, fmt.Errorf("rollback") + }) + assert.Error(t, err) + + has, err = engine.Exist(&TestTx{Msg: "hello"}) + assert.NoError(t, err) + assert.EqualValues(t, false, has) +}