🏆 事务
⭐️ 在 GORM
中,事务(Transaction
)是一种数据库操作机制,它允许你在一个单独的操作单元内执行一系列的数据库操作,并且要么全部成功提交(commit
),要么全部失败回滚(rollback
)。这种机制确保了在复杂的数据库操作中数据的一致性和完整性。
🍅 禁用事务
为了确保数据一致性,GORM
会在事务里执行写入操作(创建
、更新
、删除
)。如果没有这方面的要求,您可以在初始化时禁用它,这将获得大约 30%+
性能提升。这里在第一章连接的时候就讲说了,直接在连接配置里面配置即可
🍅 执行事务
官网示列
db.Transaction(func(tx *gorm.DB) error {
// 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
// 返回任何错误都会回滚事务
return err
}
if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
return err
}
// 返回 nil 提交事务
return nil
})
自己编写
//Many to Many创建关系
u1 := &User{
Name: "tanc",
Password: "1234567",
Tasks: []Task{
{Title: "JavaWeb大作业"},
{Title: "安卓大作业"},
{Title: "web大作业"},
},
}
//设置一个事务,使他失败
err = db.Transaction(func(tx *gorm.DB) error {
create := tx.Create(u1)
if create.Error != nil {
fmt.Println("创建失败")
return create.Error
}
var tasks Task
tx.Model(&u1).Association("Tasks").Find(&tasks)
fmt.Println("事务失败前: ", tasks)
return errors.New("手动失败")
})
if err != nil {
fmt.Println("事务失败", err.Error())
}
var tasks Task
db.Model(&u1).Association("Tasks").Find(&tasks)
fmt.Println("事务失败后: ", tasks)
//输出:
C:\Users\tanchang\AppData\Local\JetBrains\GoLand2023.3\tmp\GoLand\___1go_build_GORM_STU_GORM_Connect.exe
事务失败前: {{1 2024-07-03 17:49:39.977 +0800 CST 2024-07-03 17:49:39.977 +0800
CST {0001-01-01 00:00:00 +0000 UTC false}} JavaWeb大作业 []}
事务失败 手动失败
事务失败后: {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {00
01-01-01 00:00:00 +0000 UTC false}} []}
🍵 嵌套事务
GORM 支持嵌套事务,您可以回滚较大事务内执行的一部分操作
err = db.Transaction(func(tx *gorm.DB) error {
err2 := db.Transaction(func(tx *gorm.DB) error {
create := tx.Create(u1)
if create.Error != nil {
fmt.Println("创建失败")
return errors.New("创建用户失败 回滚")
}
return nil
})
if err2 != nil {
fmt.Println("事务失败", err2.Error())
return err2
}
var tasks Task
tx.Model(&u1).Association("Tasks").Find(&tasks)
fmt.Println("事务失败前: ", tasks)
return errors.New("手动失败")
})
🍅 手动事务
Gorm
支持直接调用事务控制方法(commit
、rollback
),例如:
// 开始事务
tx := db.Begin()
// 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
tx.Create(...)
// ...
// 遇到错误时回滚事务
tx.Rollback()
// 否则,提交事务
tx.Commit()
//设置一个事务,使他失败
tx := db.Begin()
tx.Create(u1)
var tasks1 Task
tx.Model(&u1).Association("Tasks").Find(&tasks1)
fmt.Println("事务失败前: ", tasks1)
tx.Rollback()
tx.Commit()
var tasks2 Task
db.Model(&u1).Association("Tasks").Find(&tasks2)
fmt.Println("事务失败后: ", tasks2)
🍅 SavePoint、RollbackTo
GORM 提供了 SavePoint
、Rollbackto
方法,来提供保存点以及回滚至保存点功能,例如:
tx := db.Begin()
tx.Create(&user1)
tx.SavePoint("sp1")
tx.Create(&user2)
tx.RollbackTo("sp1") // Rollback user2
tx.Commit() // Commit user1