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
1. // Globally disable
2. db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
3. SkipDefaultTransaction: true,
4. })
6. // Continuous session mode
7. tx := db.Session(&Session{SkipDefaultTransaction: true})
8. tx.First(&user, 1)
9. tx.Find(&users)
10. tx.Model(&user).Update("Age", 18)
Transaction
To perform a set of operations within a transaction, the general flow is as below.
1. db.Transaction(func(tx *gorm.DB) error {
2. // do some database operations in the transaction (use 'tx' from this point, not 'db')
3. if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
4. // return any error will rollback
5. return err
6. }
8. if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
9. return err
10. }
12. // return nil will commit the whole transaction
13. return nil
14. })
Nested Transactions
GORM supports nested transactions, you can rollback a subset of operations performed within the scope of a larger transaction, for example:
1. db.Transaction(func(tx *gorm.DB) error {
2. tx.Create(&user1)
4. tx.Transaction(func(tx2 *gorm.DB) error {
5. tx2.Create(&user2)
6. return errors.New("rollback user2") // Rollback user2
7. })
9. tx.Transaction(func(tx2 *gorm.DB) error {
10. tx2.Create(&user3)
11. return nil
12. })
14. return nil
15. })
17. // Commit user1, user3
Control the transaction manually
Gorm supports calling transaction control functions (commit / rollback) directly, for example:
1. // begin a transaction
2. tx := db.Begin()
4. // do some database operations in the transaction (use 'tx' from this point, not 'db')
5. tx.Create(...)
7. // ...
9. // rollback the transaction in case of error
10. tx.Rollback()
12. // Or commit the transaction
13. tx.Commit()
A Specific Example
1. func CreateAnimals(db *gorm.DB) error {
2. // Note the use of tx as the database handle once you are within a transaction
3. tx := db.Begin()
4. defer func() {
5. if r := recover(); r != nil {
6. tx.Rollback()
7. }
8. }()
10. if err := tx.Error; err != nil {
11. return err
12. }
14. if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
15. tx.Rollback()
16. return err
17. }
19. if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
20. tx.Rollback()
21. return err
22. }
24. return tx.Commit().Error
25. }
SavePoint, RollbackTo
GORM provides SavePoint, RollbackTo to save points and roll back to a savepoint, for example:
1. tx := db.Begin()
2. tx.Create(&user1)
4. tx.SavePoint("sp1")
5. tx.Create(&user2)
6. tx.RollbackTo("sp1") // Rollback user2
8. tx.Commit() // Commit user1
