From cc2d46e5be425300e064a39868cfdb333f24e4ac Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Fri, 10 Mar 2023 17:42:38 +0800 Subject: [PATCH] reuse name for savepoints from nested transaction, close #6060 --- finisher_api.go | 17 +++++++++++++++-- tests/go.mod | 4 ++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/finisher_api.go b/finisher_api.go index f16d4f43..e6fe4666 100644 --- a/finisher_api.go +++ b/finisher_api.go @@ -6,6 +6,8 @@ import ( "fmt" "reflect" "strings" + "sync" + "sync/atomic" "gorm.io/gorm/clause" "gorm.io/gorm/logger" @@ -608,6 +610,15 @@ func (db *DB) Connection(fc func(tx *DB) error) (err error) { return fc(tx) } +var ( + savepointIdx int64 + savepointNamePool = &sync.Pool{ + New: func() interface{} { + return fmt.Sprintf("gorm_%d", atomic.AddInt64(&savepointIdx, 1)) + }, + } +) + // Transaction start a transaction as a block, return error will rollback, otherwise to commit. Transaction executes an // arbitrary number of commands in fc within a transaction. On success the changes are committed; if an error occurs // they are rolled back. @@ -617,7 +628,9 @@ func (db *DB) Transaction(fc func(tx *DB) error, opts ...*sql.TxOptions) (err er if committer, ok := db.Statement.ConnPool.(TxCommitter); ok && committer != nil { // nested transaction if !db.DisableNestedTransaction { - err = db.SavePoint(fmt.Sprintf("sp%p", fc)).Error + poolName := savepointNamePool.Get() + defer savepointNamePool.Put(poolName) + err = db.SavePoint(poolName.(string)).Error if err != nil { return } @@ -625,7 +638,7 @@ func (db *DB) Transaction(fc func(tx *DB) error, opts ...*sql.TxOptions) (err er defer func() { // Make sure to rollback when panic, Block error or Commit error if panicked || err != nil { - db.RollbackTo(fmt.Sprintf("sp%p", fc)) + db.RollbackTo(poolName.(string)) } }() } diff --git a/tests/go.mod b/tests/go.mod index e970c9f5..306a530e 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -11,10 +11,10 @@ require ( github.com/microsoft/go-mssqldb v0.20.0 // indirect golang.org/x/crypto v0.7.0 // indirect gorm.io/driver/mysql v1.4.7 - gorm.io/driver/postgres v1.4.8 + gorm.io/driver/postgres v1.5.0 gorm.io/driver/sqlite v1.4.4 gorm.io/driver/sqlserver v1.4.2 - gorm.io/gorm v1.24.6 + gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11 ) replace gorm.io/gorm => ../