自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Golang transaction 事務(wù)使用的正確姿勢(shì)

開發(fā) 后端
本文中作者展示了 golang 事務(wù)的三種寫法。

本文中作者展示了 golang 事務(wù)的三種寫法。

第一種寫法

這種寫法非常樸實(shí),程序流程也非常明確,但是事務(wù)處理與程序流程嵌入太深,容易遺漏,造成嚴(yán)重的問題

func DoSomething() (err error) {
    tx, err := db.Begin()
    if err != nil {
        return
    }


    defer func() {
        if p := recover(); p != nil {
            tx.Rollback()
            panic(p)  // re-throw panic after Rollback
        }
    }()


    if _, err = tx.Exec(...); err != nil {
        tx.Rollback()
        return
    }
    if _, err = tx.Exec(...); err != nil {
        tx.Rollback()
        return
    }
    // ...


    err = tx.Commit()
    return
}

第二種寫法

下面這種寫法把事務(wù)處理從程序流程抽離了出來,不容易遺漏,但是作用域是整個(gè)函數(shù),程序流程不是很清晰

func DoSomething() (err error) {
    txerr := db.Begin()
    if err != nil {
        return
    }


    defer func() {
        if p := recover(); p != nil {
            tx.Rollback()
            panic(p// re-throw panic after Rollback
        } else if err != nil {
            tx.Rollback()
        } else {
            err = tx.Commit()
        }
    }()


    if _err = tx.Exec(...); err != nil {
        return
    }
    if _err = tx.Exec(...); err != nil {
        return
    }
    // ...
    return
}

第三種寫法

寫法三是對(duì)寫法二的進(jìn)一步封裝,寫法高級(jí)一點(diǎn),缺點(diǎn)同上

func Transact(db *sql.DBtxFunc func(*sql.Txerror) (err error) {
    txerr := db.Begin()
    if err != nil {
        return
    }


    defer func() {
        if p := recover(); p != nil {
            tx.Rollback()
            panic(p// re-throw panic after Rollback
        } else if err != nil {
            tx.Rollback()
        } else {
            err = tx.Commit()
        }
    }()


    err = txFunc(tx)
    return err
}


func DoSomething() error {
    return Transact(dbfunc (tx *sql.Txerror {
        if _err := tx.Exec(...); err != nil {
            return err
        }
        if _err := tx.Exec(...); err != nil {
            return err
        }
    })
}

我的寫法

經(jīng)過總結(jié)和實(shí)驗(yàn),我采用了下面這種寫法,defer tx.Rollback() 使得事務(wù)回滾始終得到執(zhí)行。當(dāng) tx.Commit() 執(zhí)行后,tx.Rollback() 起到關(guān)閉事務(wù)的作用, 當(dāng)程序因?yàn)槟硞€(gè)錯(cuò)誤中止,tx.Rollback() 起到回滾事務(wù),同事關(guān)閉事務(wù)的作用。

普通場(chǎng)景

func DoSomething() (err error) {
  tx_ := db.Begin()
  defer tx.Rollback()

  if _err = tx.Exec(...); err != nil {
      return
  }
  if _err = tx.Exec(...); err != nil {
      return
  }
  // ...


  err = tx.Commit()
  return
}

循環(huán)場(chǎng)景

(1) 小事務(wù) 每次循環(huán)提交一次 在循環(huán)內(nèi)部使用這種寫法的時(shí)候,defer 不能使用,所以要把事務(wù)部分抽離到獨(dú)立的函數(shù)當(dāng)中

func DoSomething() (err error) {
    tx_ := db.Begin()
    defer tx.Rollback()

    if _err = tx.Exec(...); err != nil {
        return
    }
    if _err = tx.Exec(...); err != nil {
        return
    }
    // ...


    err = tx.Commit()
    return
}


for {
    if err := DoSomething(); err != nil{
         // ...
    }
}

(2) 大事務(wù) 批量提交 大事務(wù)的場(chǎng)景和普通場(chǎng)景是一樣的,沒有任何區(qū)別

func DoSomething() (err error) {
    tx_ := db.Begin()
    defer tx.Rollback()

    for{
        if _err = tx.Exec(...); err != nil {
            return
        }
        if _err = tx.Exec(...); err != nil {
            return
        }
        // ...
    }

    err = tx.Commit()
    return
}


責(zé)任編輯:龐桂玉 來源: 馬哥Linux運(yùn)維
相關(guān)推薦

2017-02-23 15:37:44

OptionObject容器

2017-07-10 13:09:45

前端Flexbox

2021-09-15 16:20:02

Spring BootFilterJava

2016-01-05 11:28:20

按需付費(fèi)云計(jì)算docker

2021-07-13 07:31:26

Springboot編程事務(wù)管理

2018-01-11 15:31:39

命令Linux關(guān)機(jī)

2016-05-09 10:41:03

算法分析開發(fā)

2017-03-16 11:39:33

Openstack源碼姿勢(shì)

2023-01-30 07:41:43

2020-08-31 06:54:37

注解脫敏ELK

2021-07-12 11:35:13

Go協(xié)程Goroutine

2017-10-12 11:30:34

Spark代碼PR

2021-01-08 08:10:34

MySQL表空間回收

2021-10-08 08:38:00

Pipelineshell命令Jenkins

2016-12-12 08:48:24

2019-12-27 15:58:57

大數(shù)據(jù)IT互聯(lián)網(wǎng)

2024-09-25 08:22:06

2019-10-30 17:06:50

AWS物聯(lián)網(wǎng)IoT

2019-01-02 10:49:54

Tomcat內(nèi)存HotSpot VM

2020-02-24 15:26:40

Python短信免費(fèi)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)