事务

原文:https://gorm.io/docs/transactions.html

禁用默认事务 Disable Default Transaction

GORM perform write (create/update/delete) operations run inside a transaction to ensure data consistency, you can disable it during initialization if it is not required, you will gain about 30%+ performance improvement after that

​ GORM在执行写(创建/更新/删除)操作时,会运行在事务中以确保数据一致性。如果在初始化过程中不需要,可以在此处禁用它,之后将获得大约30%+的性能提升。

1 2 3 4 5 6 7 8 9 10
// 全局禁用 Globally disable db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{ SkipDefaultTransaction: true, }) // 连续会话模式 Continuous session mode tx := db.Session(&Session{SkipDefaultTransaction: true}) tx.First(&user, 1) tx.Find(&users) tx.Model(&user).Update("Age", 18)

事务 Transaction

To perform a set of operations within a transaction, the general flow is as below.

​ 要执行一组操作的事务,一般流程如下。

1 2 3 4 5 6 7 8 9 10 11 12 13 14
db.Transaction(func(tx *gorm.DB) error { // 在此点之后的数据库操作中使用'tx'(而不是'db')进行一些数据库操作 do some database operations in the transaction (use 'tx' from this point, not 'db') if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil { // 返回任何错误都将回滚 return any error will rollback return err } if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil { return err } // 返回nil将提交整个事务 return nil will commit the whole transaction return nil })

嵌套事务 Nested Transactions

GORM supports nested transactions, you can rollback a subset of operations performed within the scope of a larger transaction, for example:

​ GORM支持嵌套事务,您可以回滚在更大事务范围内执行的操作的一部分,例如:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
db.Transaction(func(tx *gorm.DB) error { tx.Create(&user1) tx.Transaction(func(tx2 *gorm.DB) error { tx2.Create(&user2) return errors.New("rollback user2") // Rollback user2 }) tx.Transaction(func(tx2 *gorm.DB) error { tx2.Create(&user3) return nil }) return nil }) // 提交 user1, user3 Commit user1, user3

手动控制事务 Control the transaction manually

Gorm supports calling transaction control functions (commit / rollback) directly, for example:

​ Gorm支持直接调用事务控制函数(提交 / 回滚),例如:

1 2 3 4 5 6 7 8 9 10 11 12 13
// 开始一个事务 begin a transaction tx := db.Begin() // 在此点之后的数据库操作中使用'tx'(而不是'db')进行一些数据库操作 do some database operations in the transaction (use 'tx' from this point, not 'db') tx.Create(...) // ... // 发生错误时的回滚事务 rollback the transaction in case of error tx.Rollback() // 或者提交事务 Or commit the transaction tx.Commit()

一个具体的例子 A Specific Example

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
func CreateAnimals(db *gorm.DB) error { // 注意一旦你进入事务,就使用tx作为数据库句柄 Note the use of tx as the database handle once you are within a transaction tx := db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() if err := tx.Error; err != nil { return err } if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil { tx.Rollback() return err } if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil { tx.Rollback() return err } return tx.Commit().Error }

SavePoint, RollbackTo

GORM provides SavePoint, RollbackTo to save points and roll back to a savepoint, for example:

​ GORM提供SavePointRollbackTo来保存点和回滚到保存点,例如:

1 2 3 4 5 6 7 8
tx := db.Begin() tx.Create(&user1) tx.SavePoint("sp1") tx.Create(&user2) tx.RollbackTo("sp1") // Rollback user2 tx.Commit() // Commit user1
最后修改 October 10, 2024: 更新 (a4b8f854)