タイトルどおり、Goでトランザクションを張って処理を実行してみます。
コード
ポイントは、defer tx.Rollback()で、ロールバックを予約しておくことです。
こうしておくことで、処理がコケたときに自動でロールバックが実行されるようになります。
コミット後にロールバックが実行されても処理が戻ることはないのでこれでOKです。
package main
import (
"database/sql"
"fmt"
"log"
"os"
_ "github.com/go-sql-driver/mysql"
)
var (
dbUser = os.Getenv("DB_USER")
dbPassword = os.Getenv("DB_PASSWORD")
dbDatabase = os.Getenv("DB_NAME")
dbConn = fmt.Sprintf("%s:%s@tcp(127.0.0.1:3306)/%s?parseTime=true", dbUser, dbPassword, dbDatabase)
)
func main() {
db, err := sql.Open("mysql", dbConn)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// トランザクションを開始する
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
defer tx.Rollback()
// トランザクション内でクエリを実行する
_, err = tx.Exec("INSERT INTO users (name, email) VALUES (?, ?)", "TEST TEST", "test@example.com")
if err != nil {
log.Fatal(err)
}
_, err = tx.Exec("INSERT INTO users (name, email) VALUES (?, ?)", "TEST TEST", "test@example.com")
if err != nil {
log.Fatal(err)
}
// トランザクションをコミットする
err = tx.Commit()
if err != nil {
log.Fatal(err)
}
fmt.Println("トランザクションが正常に完了しました")
}
動かしてみる
go run main.go
トランザクションが正常に完了しました