2020-05-31 13:51:43 +03:00
|
|
|
package tests_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"errors"
|
|
|
|
"testing"
|
|
|
|
|
2020-06-02 04:16:07 +03:00
|
|
|
"gorm.io/gorm"
|
2020-06-02 05:34:50 +03:00
|
|
|
. "gorm.io/gorm/utils/tests"
|
2020-05-31 13:51:43 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestTransaction(t *testing.T) {
|
|
|
|
tx := DB.Begin()
|
|
|
|
user := *GetUser("transcation", Config{})
|
|
|
|
|
|
|
|
if err := tx.Save(&user).Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("No error should raise, but got %v", err)
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := tx.First(&User{}, "name = ?", "transcation").Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Should find saved record, but got %v", err)
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if sqlTx, ok := tx.Statement.ConnPool.(*sql.Tx); !ok || sqlTx == nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Should return the underlying sql.Tx")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
|
|
|
if err := DB.First(&User{}, "name = ?", "transcation").Error; err == nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Should not find record after rollback, but got %v", err)
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
tx2 := DB.Begin()
|
|
|
|
user2 := *GetUser("transcation-2", Config{})
|
|
|
|
if err := tx2.Save(&user2).Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("No error should raise, but got %v", err)
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := tx2.First(&User{}, "name = ?", "transcation-2").Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Should find saved record, but got %v", err)
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
tx2.Commit()
|
|
|
|
|
|
|
|
if err := DB.First(&User{}, "name = ?", "transcation-2").Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Should be able to find committed record, but got %v", err)
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTransactionWithBlock(t *testing.T) {
|
|
|
|
assertPanic := func(f func()) {
|
|
|
|
defer func() {
|
|
|
|
if r := recover(); r == nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("The code did not panic")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
}()
|
|
|
|
f()
|
|
|
|
}
|
|
|
|
|
|
|
|
// rollback
|
|
|
|
err := DB.Transaction(func(tx *gorm.DB) error {
|
|
|
|
user := *GetUser("transcation-block", Config{})
|
|
|
|
if err := tx.Save(&user).Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("No error should raise")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := tx.First(&User{}, "name = ?", user.Name).Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Should find saved record")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return errors.New("the error message")
|
|
|
|
})
|
|
|
|
|
|
|
|
if err.Error() != "the error message" {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Transaction return error will equal the block returns error")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := DB.First(&User{}, "name = ?", "transcation-block").Error; err == nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Should not find record after rollback")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// commit
|
|
|
|
DB.Transaction(func(tx *gorm.DB) error {
|
|
|
|
user := *GetUser("transcation-block-2", Config{})
|
|
|
|
if err := tx.Save(&user).Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("No error should raise")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := tx.First(&User{}, "name = ?", user.Name).Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Should find saved record")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
|
|
|
if err := DB.First(&User{}, "name = ?", "transcation-block-2").Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Should be able to find committed record")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// panic will rollback
|
|
|
|
assertPanic(func() {
|
|
|
|
DB.Transaction(func(tx *gorm.DB) error {
|
|
|
|
user := *GetUser("transcation-block-3", Config{})
|
|
|
|
if err := tx.Save(&user).Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("No error should raise")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := tx.First(&User{}, "name = ?", user.Name).Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Should find saved record")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
panic("force panic")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
if err := DB.First(&User{}, "name = ?", "transcation-block-3").Error; err == nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Should not find record after panic rollback")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTransactionRaiseErrorOnRollbackAfterCommit(t *testing.T) {
|
|
|
|
tx := DB.Begin()
|
|
|
|
user := User{Name: "transcation"}
|
|
|
|
if err := tx.Save(&user).Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("No error should raise")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := tx.Commit().Error; err != nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Commit should not raise error")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := tx.Rollback().Error; err == nil {
|
2020-05-31 18:55:56 +03:00
|
|
|
t.Fatalf("Rollback after commit should raise error")
|
2020-05-31 13:51:43 +03:00
|
|
|
}
|
|
|
|
}
|