日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
Golangtransaction事務(wù)使用的正確姿勢(shì)

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

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛(ài)。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶,將通過(guò)不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名與空間、虛擬空間、營(yíng)銷(xiāo)軟件、網(wǎng)站建設(shè)、彰武網(wǎng)站維護(hù)、網(wǎng)站推廣。

第一種寫(xiě)法

這種寫(xiě)法非常樸實(shí),程序流程也非常明確,但是事務(wù)處理與程序流程嵌入太深,容易遺漏,造成嚴(yán)重的問(wè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
}

第二種寫(xiě)法

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

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
        } 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
}

第三種寫(xiě)法

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

func Transact(db *sql.DB, txFunc func(*sql.Tx) error) (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
        } else if err != nil {
            tx.Rollback()
        } else {
            err = tx.Commit()
        }
    }()


    err = txFunc(tx)
    return err
}


func DoSomething() error {
    return Transact(db, func (tx *sql.Tx) error {
        if _, err := tx.Exec(...); err != nil {
            return err
        }
        if _, err := tx.Exec(...); err != nil {
            return err
        }
    })
}

我的寫(xiě)法

經(jīng)過(guò)總結(jié)和實(shí)驗(yàn),我采用了下面這種寫(xiě)法,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)部使用這種寫(xiě)法的時(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)景是一樣的,沒(méi)有任何區(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
}

文章標(biāo)題:Golangtransaction事務(wù)使用的正確姿勢(shì)
分享網(wǎng)址:http://m.5511xx.com/article/dpdigsc.html