0
0

はじめに

タイトルどおり、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

トランザクションが正常に完了しました

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0