網頁

2022/1/5

Golang 資料庫交易回滾 database sql transaction rollback

Golang sql執行多筆資料異動交易時若錯誤發生可使用sql.Tx.Rollback()回滾。


範例環境:

  • Go 1.17
  • PostgreSQL 14
  • github.com/lib/pq


範例

下面程式對PostgreSQL資料庫執行交易。在createEmployee()中使用sql.DB.Begin()開始一個交易/事務(transaction session)並返回sql.Tx交易物件。利用defer sql.Tx.Rollback()來在錯誤發生時回滾先前的異動;若無錯誤調用sql.Tx.Commit()完成交易。交易提交後調用sql.Tx.Rollback()no-op操作,所以不影響已完成的交易。

package main

import (
    "database/sql"
    "fmt"
    "log"
    "time"

    _ "github.com/lib/pq"
)

const (
    HOST     = "localhost"
    PORT     = "5432"
    DATABASE = "postgres"
    USER     = "<usernmae>"
    PASSWORD = "<password>"
    SSL      = "disable"
)

func connect() *sql.DB {
    driver := "postgres"
    dsn := fmt.Sprintf(
        "host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
        HOST, PORT, USER, PASSWORD, DATABASE, SSL)

    db, err := sql.Open(driver, dsn)
    if err != nil {
        log.Println(err)
    }
    return db
}

func main() {
    db := connect()
    if err := createEmployee(db, "john", 33); err != nil {
        fmt.Println(err)
    }
}

func createEmployee(db *sql.DB, name string, age int) error {
    tx, err := db.Begin() // 開始一個交易

    if err != nil {
        return err
    }
    defer tx.Rollback() // 確保錯誤發生時rollback.

    sql := "INSERT INTO employee (name, age, created_at) VALUES ($1, $2, $3)"

    _, err = tx.Exec(sql, "john", 33, time.Now()) // 執行DML sql並帶入參數
    if err != nil {
        return err
    }

    if err = tx.Commit(); err != nil { // 提交
        return err
    }

    return nil
}

github


沒有留言:

張貼留言