Fix failed to create second record in same transaction, close #3060

This commit is contained in:
Jinzhu 2020-06-19 12:38:03 +08:00
parent 07960fe661
commit 2c1b04a2cf
4 changed files with 19 additions and 3 deletions

View File

@ -7,7 +7,7 @@ import (
func BeginTransaction(db *gorm.DB) { func BeginTransaction(db *gorm.DB) {
if tx := db.Begin(); tx.Error == nil { if tx := db.Begin(); tx.Error == nil {
db.Statement.ConnPool = tx.Statement.ConnPool db.Statement.ConnPool = tx.Statement.ConnPool
tx.InstanceSet("gorm:started_transaction", true) db.InstanceSet("gorm:started_transaction", true)
} else { } else {
tx.Error = nil tx.Error = nil
} }

View File

@ -351,7 +351,7 @@ func (db *DB) Transaction(fc func(tx *DB) error, opts ...*sql.TxOptions) (err er
} }
}() }()
err = fc(tx.Session(&Session{})) err = fc(tx)
if err == nil { if err == nil {
err = tx.Commit().Error err = tx.Commit().Error
@ -364,7 +364,8 @@ func (db *DB) Transaction(fc func(tx *DB) error, opts ...*sql.TxOptions) (err er
// Begin begins a transaction // Begin begins a transaction
func (db *DB) Begin(opts ...*sql.TxOptions) *DB { func (db *DB) Begin(opts ...*sql.TxOptions) *DB {
var ( var (
tx = db.getInstance() // clone statement
tx = db.Session(&Session{WithConditions: true, Context: db.Statement.Context})
opt *sql.TxOptions opt *sql.TxOptions
err error err error
) )

View File

@ -351,5 +351,10 @@ func (stmt *Statement) clone() *Statement {
newStmt.Joins[k] = j newStmt.Joins[k] = j
} }
stmt.Settings.Range(func(k, v interface{}) bool {
newStmt.Settings.Store(k, v)
return true
})
return newStmt return newStmt
} }

View File

@ -20,6 +20,16 @@ func TestTransaction(t *testing.T) {
t.Fatalf("Should find saved record, but got %v", err) t.Fatalf("Should find saved record, but got %v", err)
} }
user1 := *GetUser("transaction1-1", Config{})
if err := tx.Save(&user1).Error; err != nil {
t.Fatalf("No error should raise, but got %v", err)
}
if err := tx.First(&User{}, "name = ?", user1.Name).Error; err != nil {
t.Fatalf("Should find saved record, but got %v", err)
}
if sqlTx, ok := tx.Statement.ConnPool.(gorm.TxCommitter); !ok || sqlTx == nil { if sqlTx, ok := tx.Statement.ConnPool.(gorm.TxCommitter); !ok || sqlTx == nil {
t.Fatalf("Should return the underlying sql.Tx") t.Fatalf("Should return the underlying sql.Tx")
} }