tx, err := db.Begin() if err != nil { log.Fatal(err) } defer func() { if r := recover(); r != nil { tx.Rollback() } }() // execute some SQL within the transaction stmt, err := tx.Prepare("INSERT INTO users (name, email) VALUES (?, ?)") if err != nil { tx.Rollback() log.Fatal(err) } defer stmt.Close() _, err = stmt.Exec("Bob", "[email protected]") if err != nil { tx.Rollback() log.Fatal(err) } _, err = stmt.Exec("Alice", "[email protected]") if err != nil { tx.Rollback() log.Fatal(err) } tx.Commit()In this example, we first create a new transaction using the `Begin` method of our `db` object. We then defer a call to a function that will roll back the transaction if any errors occur during the process. We then prepare a SQL statement using the `Prepare` method of our transaction object. We pass in a SQL query that inserts rows into our `users` table. We then execute the statement twice, once for "Bob" and once for "Alice", using the `Exec` method. If any errors occur during the execution of either of these statements, we roll back the transaction and log the error. Finally, if everything succeeds, we commit the transaction using the `Commit` method. In this example, we're using the `database/sql` package and the native SQL driver for our underlying database. However, other database packages may also provide their own `Tx` types and transaction management methods.