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
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')
iferr:=tx.Create(&Animal{Name:"Giraffe"}).Error;err!=nil{// 返回任何错误都将回滚 return any error will rollback
returnerr}iferr:=tx.Create(&Animal{Name:"Lion"}).Error;err!=nil{returnerr}// 返回nil将提交整个事务 return nil will commit the whole transaction
returnnil})
嵌套事务 Nested Transactions
GORM supports nested transactions, you can rollback a subset of operations performed within the scope of a larger transaction, for example:
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()
funcCreateAnimals(db*gorm.DB)error{// 注意一旦你进入事务,就使用tx作为数据库句柄 Note the use of tx as the database handle once you are within a transaction
tx:=db.Begin()deferfunc(){ifr:=recover();r!=nil{tx.Rollback()}}()iferr:=tx.Error;err!=nil{returnerr}iferr:=tx.Create(&Animal{Name:"Giraffe"}).Error;err!=nil{tx.Rollback()returnerr}iferr:=tx.Create(&Animal{Name:"Lion"}).Error;err!=nil{tx.Rollback()returnerr}returntx.Commit().Error}
SavePoint, RollbackTo
GORM provides SavePoint, RollbackTo to save points and roll back to a savepoint, for example: