From adca9222abe5a0a4442b1f9c46eeba1cb4d7e3f4 Mon Sep 17 00:00:00 2001 From: jflyfox Date: Tue, 22 Jun 2021 17:42:31 +0800 Subject: [PATCH] improve transaction feature for package gdb --- database/gdb/gdb_core_transaction.go | 11 +++++++++++ database/gdb/gdb_z_mysql_transaction_test.go | 10 +++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/database/gdb/gdb_core_transaction.go b/database/gdb/gdb_core_transaction.go index 1f09850e5..0252f1096 100644 --- a/database/gdb/gdb_core_transaction.go +++ b/database/gdb/gdb_core_transaction.go @@ -28,6 +28,7 @@ type TX struct { master *sql.DB // master is the raw and underlying database manager. transactionId string // transactionId is an unique id generated by this object for this transaction. transactionCount int // transactionCount marks the times that Begins. + isClosed bool // isClosed marks this transaction has already been committed or rolled back. } const ( @@ -162,6 +163,9 @@ func TXFromCtx(ctx context.Context, group string) *TX { v := ctx.Value(transactionKeyForContext(group)) if v != nil { tx := v.(*TX) + if tx.IsClosed() { + return nil + } tx.ctx = ctx return tx } @@ -210,6 +214,7 @@ func (tx *TX) Commit() error { IsTransaction: true, } ) + tx.isClosed = true tx.db.GetCore().addSqlToTracing(tx.ctx, sqlObj) if tx.db.GetDebug() { tx.db.GetCore().writeSqlToLogger(tx.ctx, sqlObj) @@ -243,6 +248,7 @@ func (tx *TX) Rollback() error { IsTransaction: true, } ) + tx.isClosed = true tx.db.GetCore().addSqlToTracing(tx.ctx, sqlObj) if tx.db.GetDebug() { tx.db.GetCore().writeSqlToLogger(tx.ctx, sqlObj) @@ -250,6 +256,11 @@ func (tx *TX) Rollback() error { return err } +// IsClosed checks and returns this transaction has already been committed or rolled back. +func (tx *TX) IsClosed() bool { + return tx.isClosed +} + // Begin starts a nested transaction procedure. func (tx *TX) Begin() error { _, err := tx.Exec("SAVEPOINT " + tx.transactionKeyForNestedPoint()) diff --git a/database/gdb/gdb_z_mysql_transaction_test.go b/database/gdb/gdb_z_mysql_transaction_test.go index 61d68ce68..669055145 100644 --- a/database/gdb/gdb_z_mysql_transaction_test.go +++ b/database/gdb/gdb_z_mysql_transaction_test.go @@ -666,7 +666,6 @@ func Test_TX_GetScan(t *testing.T) { } func Test_TX_Delete(t *testing.T) { - gtest.C(t, func(t *gtest.T) { table := createInitTable() defer dropTable(table) @@ -685,6 +684,8 @@ func Test_TX_Delete(t *testing.T) { } else { t.Assert(n, 0) } + + t.Assert(tx.IsClosed(), true) }) gtest.C(t, func(t *gtest.T) { @@ -711,6 +712,8 @@ func Test_TX_Delete(t *testing.T) { t.Assert(n, TableSize) t.AssertNE(n, 0) } + + t.Assert(tx.IsClosed(), true) }) } @@ -721,7 +724,7 @@ func Test_Transaction(t *testing.T) { gtest.C(t, func(t *gtest.T) { ctx := context.TODO() err := db.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { - if _, err := tx.Replace(table, g.Map{ + if _, err := tx.Ctx(ctx).Replace(table, g.Map{ "id": 1, "passport": "USER_1", "password": "PASS_1", @@ -730,11 +733,12 @@ func Test_Transaction(t *testing.T) { }); err != nil { t.Error(err) } + t.Assert(tx.IsClosed(), false) return gerror.New("error") }) t.AssertNE(err, nil) - if value, err := db.Model(table).Fields("nickname").Where("id", 1).Value(); err != nil { + if value, err := db.Model(table).Ctx(ctx).Fields("nickname").Where("id", 1).Value(); err != nil { gtest.Error(err) } else { t.Assert(value.String(), "name_1")