Gorm uses specifications and best practices for reference only

delete

Like Update, when deleting a record, you need to specify its primary key, so it is mandatory that deletion be used with the WHERE clause, even though bulk deletion is not triggered by default:

db.Delete(&email) // Not recommended

db.Where("name = ?"."wzy").Delete(&email) // Delete with additional conditions, recommended
Copy the code

Transaction control

Transaction control creates a new database connection in GORM, as shown in the following example on the GORM website:

// Start transaction
tx := db.Begin()

// Perform some DB operations in a transaction (from here you should use 'tx' instead of 'db')
tx.Create(...)

// ...

// Roll back the transaction if an error is encountered
tx.Rollback()

// Otherwise, commit the transaction
tx.Commit()
Copy the code

The official website does not mention that you should use TX for database connections. If the previous function returns error, the code will rollback manually. For example:

func foo(a){
    var err error
    
    tx := db.Begin()
    iferr = foo1(tx); err ! =nil {
        tx.Rollback()
    }
    
    iferr = foo1(tx); err ! =nil {
        tx.Rollback()
    }
    
    tx.Commit()
}

func foo1(dbs... *gorm.DB)error{}func foo2(dbs... *gorm.DB)error{}Copy the code

Having a rollback on every branch is not only inelegant, but also highly repetitive. Therefore, it is recommended that for each possible error situation, defer handles the error and rolls back:

func foo(a){
    var err error
    
    tx := db.Begin()
    defer handleError(&err) // If the error does not exist, commit
    iferr = foo1(tx); err ! =nil {
        return
    }
    
    iferr = foo1(tx); err ! =nil {
        return
    }
    
    return
}

func foo1(dbs... *gorm.DB)error{}func foo2(dbs... *gorm.DB)error{}Copy the code

The handleError function is responsible for determining whether an error occurred during the transaction, rolling it back if it did, and committing it if it did not:

handleError := func(err *error) {
    if *err == nil {
      err = &(tx.Commit().Error)
    }
    if*err ! =nil {
      tx.Rollback()
    }
}
Copy the code

We haven’t found a good scenario to use nested transactions yet, but welcome to add.