From c170af11e909098311b0c2f188b7917803e714e9 Mon Sep 17 00:00:00 2001 From: kinggo <30891428+longlihale@users.noreply.github.com> Date: Wed, 3 Nov 2021 13:39:52 +0800 Subject: [PATCH] fix connections leak (#4826) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix connections leak * fix connections leak * fix connections leak * fix connections leak Co-authored-by: 李龙 --- callbacks/transaction.go | 2 +- finisher_api.go | 68 ++++++++++++++++++++-------------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/callbacks/transaction.go b/callbacks/transaction.go index 8ba2ba3b..f116d19f 100644 --- a/callbacks/transaction.go +++ b/callbacks/transaction.go @@ -5,7 +5,7 @@ import ( ) func BeginTransaction(db *gorm.DB) { - if !db.Config.SkipDefaultTransaction { + if !db.Config.SkipDefaultTransaction && db.Error == nil { if tx := db.Begin(); tx.Error == nil { db.Statement.ConnPool = tx.Statement.ConnPool db.InstanceSet("gorm:started_transaction", true) diff --git a/finisher_api.go b/finisher_api.go index 48eb94c5..efdbd563 100644 --- a/finisher_api.go +++ b/finisher_api.go @@ -285,44 +285,44 @@ func (db *DB) FirstOrCreate(dest interface{}, conds ...interface{}) (tx *DB) { queryTx := db.Limit(1).Order(clause.OrderByColumn{ Column: clause.Column{Table: clause.CurrentTable, Name: clause.PrimaryKey}, }) - - if tx = queryTx.Find(dest, conds...); queryTx.RowsAffected == 0 { - if c, ok := tx.Statement.Clauses["WHERE"]; ok { - if where, ok := c.Expression.(clause.Where); ok { - tx.assignInterfacesToValue(where.Exprs) - } - } - - // initialize with attrs, conds - if len(tx.Statement.attrs) > 0 { - tx.assignInterfacesToValue(tx.Statement.attrs...) - } - - // initialize with attrs, conds - if len(tx.Statement.assigns) > 0 { - tx.assignInterfacesToValue(tx.Statement.assigns...) - } - - return tx.Create(dest) - } else if len(db.Statement.assigns) > 0 { - exprs := tx.Statement.BuildCondition(db.Statement.assigns[0], db.Statement.assigns[1:]...) - assigns := map[string]interface{}{} - for _, expr := range exprs { - if eq, ok := expr.(clause.Eq); ok { - switch column := eq.Column.(type) { - case string: - assigns[column] = eq.Value - case clause.Column: - assigns[column.Name] = eq.Value - default: + if tx = queryTx.Find(dest, conds...); tx.Error == nil { + if tx.RowsAffected == 0 { + if c, ok := tx.Statement.Clauses["WHERE"]; ok { + if where, ok := c.Expression.(clause.Where); ok { + tx.assignInterfacesToValue(where.Exprs) } } + + // initialize with attrs, conds + if len(tx.Statement.attrs) > 0 { + tx.assignInterfacesToValue(tx.Statement.attrs...) + } + + // initialize with attrs, conds + if len(tx.Statement.assigns) > 0 { + tx.assignInterfacesToValue(tx.Statement.assigns...) + } + + return tx.Create(dest) + } else if len(db.Statement.assigns) > 0 { + exprs := tx.Statement.BuildCondition(db.Statement.assigns[0], db.Statement.assigns[1:]...) + assigns := map[string]interface{}{} + for _, expr := range exprs { + if eq, ok := expr.(clause.Eq); ok { + switch column := eq.Column.(type) { + case string: + assigns[column] = eq.Value + case clause.Column: + assigns[column.Name] = eq.Value + default: + } + } + } + + return tx.Model(dest).Updates(assigns) } - - return tx.Model(dest).Updates(assigns) } - - return db + return tx } // Update update attributes with callbacks, refer: https://gorm.io/docs/update.html#Update-Changed-Fields