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.
db.Transaction(func(tx *gorm.DB)error { // 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 }
Gorm supports calling transaction control functions (commit / rollback) directly, for example:
// begin a transaction tx := db.Begin()
// 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()
// ...
// begin a transaction tx := db.Begin()
// 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
funcCreateAnimals(db *gorm.DB)error { // Note the use of tx as the database handle once you are within a transaction tx := db.Begin() deferfunc() { if r := recover(); r != nil { tx.Rollback() } }()