Merge branch 'master' into master

This commit is contained in:
Jinzhu 2019-12-05 18:26:04 +08:00 committed by GitHub
commit 29d9a513c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 98 additions and 1 deletions

2
go.mod
View File

@ -9,5 +9,5 @@ require (
github.com/jinzhu/inflection v1.0.0
github.com/jinzhu/now v1.0.1
github.com/lib/pq v1.1.1
github.com/mattn/go-sqlite3 v1.11.0
github.com/mattn/go-sqlite3 v2.0.1+incompatible
)

4
go.sum
View File

@ -54,6 +54,10 @@ github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.12.0 h1:u/x3mp++qUxvYfulZ4HKOvVO0JWhk7HtE8lWhbGz/Do=
github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=

22
main.go
View File

@ -525,6 +525,28 @@ func (s *DB) Debug() *DB {
return s.clone().LogMode(true)
}
// Transaction start a transaction as a block,
// return error will rollback, otherwise to commit.
func (s *DB) Transaction(fc func(tx *DB) error) (err error) {
panicked := true
tx := s.Begin()
defer func() {
// Make sure to rollback when panic, Block error or Commit error
if panicked || err != nil {
tx.Rollback()
}
}()
err = fc(tx)
if err == nil {
err = tx.Commit().Error
}
panicked = false
return
}
// Begin begins a transaction
func (s *DB) Begin() *DB {
return s.BeginTx(context.Background(), &sql.TxOptions{})

View File

@ -8,6 +8,7 @@ import (
"context"
"database/sql"
"database/sql/driver"
"errors"
"fmt"
"os"
"path/filepath"
@ -469,6 +470,76 @@ func TestTransaction(t *testing.T) {
}
}
func assertPanic(t *testing.T, f func()) {
defer func() {
if r := recover(); r == nil {
t.Errorf("The code did not panic")
}
}()
f()
}
func TestTransactionWithBlock(t *testing.T) {
// rollback
err := DB.Transaction(func(tx *gorm.DB) error {
u := User{Name: "transcation"}
if err := tx.Save(&u).Error; err != nil {
t.Errorf("No error should raise")
}
if err := tx.First(&User{}, "name = ?", "transcation").Error; err != nil {
t.Errorf("Should find saved record")
}
return errors.New("the error message")
})
if err.Error() != "the error message" {
t.Errorf("Transaction return error will equal the block returns error")
}
if err := DB.First(&User{}, "name = ?", "transcation").Error; err == nil {
t.Errorf("Should not find record after rollback")
}
// commit
DB.Transaction(func(tx *gorm.DB) error {
u2 := User{Name: "transcation-2"}
if err := tx.Save(&u2).Error; err != nil {
t.Errorf("No error should raise")
}
if err := tx.First(&User{}, "name = ?", "transcation-2").Error; err != nil {
t.Errorf("Should find saved record")
}
return nil
})
if err := DB.First(&User{}, "name = ?", "transcation-2").Error; err != nil {
t.Errorf("Should be able to find committed record")
}
// panic will rollback
assertPanic(t, func() {
DB.Transaction(func(tx *gorm.DB) error {
u3 := User{Name: "transcation-3"}
if err := tx.Save(&u3).Error; err != nil {
t.Errorf("No error should raise")
}
if err := tx.First(&User{}, "name = ?", "transcation-3").Error; err != nil {
t.Errorf("Should find saved record")
}
panic("force panic")
})
})
if err := DB.First(&User{}, "name = ?", "transcation").Error; err == nil {
t.Errorf("Should not find record after panic rollback")
}
}
func TestTransaction_NoErrorOnRollbackAfterCommit(t *testing.T) {
tx := DB.Begin()
u := User{Name: "transcation"}