中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

golang中如何實現db事務的統一封裝

發布時間:2021-12-10 14:45:31 來源:億速云 閱讀:257 作者:小新 欄目:開發技術

小編給大家分享一下golang中如何實現db事務的統一封裝,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

    事務處理的流程示例

    database := db.DB
        tx, err := database.Begin()
        if err != nil {
            return err
        }
        stmt, err := tx.Prepare(sqlQuery)
        if err != nil {
            tx.Rollback()
            return err
        }
        _, err = stmt.Exec(paras...)
        if err != nil {
            tx.Rollback()
            return err
        }
        err = tx.Commit()
        if err != nil {
            tx.Rollback()
            return err
        }

    以上是我們使用事務時的一般操作,如果每做一次事務的操作均要進行重新寫一遍代碼豈不是很麻煩,尤其是出錯時,Rollback需要多次在不同錯誤的地方的進行調用處理。

    簡單封裝

    偷懶第一步

    采用defer處理Rollback

    defer tx.Rollback()

    無論成功與否,均進行Rollback操作,只是有點影響,如果成功還調用Rollback的話,將會報錯。雖然可以忽略,但作為程序員,有必要進一步調整。

    偷懶第二步

    根據執行結果來選擇執行Rollback,避免無效使用。

    defer func() { //根據執行結果選擇執行Rollback
            if err != nil && tx != nil {
            log.Println("ExecSqlWithTransaction defer err :", err)
                tx.Rollback()
            }
        }()

    如此,我們就可以根據事務的執行結果決定是否Rollback了。

    偷懶第三步

    封裝,以上代碼本身就具有極大的普適性,因此,我們抽出通用的參數,將此過程封裝成一個func,以后就可以直接調用了。

    func ExecSqlWithTransaction(database *sql.DB, query string, args ...interface{}) (err error) {
        tx, err := database.Begin()
        if err != nil {
            return err
        }
        defer func() {
            if err != nil && tx != nil {
                tx.Rollback()
            }
        }()
        stmt, err := tx.Prepare(query)
        if err != nil {
            return err
        }
        defer stmt.Close()
        _, err = stmt.Exec(args...)
        if err != nil {
            return err
        }
        return tx.Commit()
    }

    封裝后我們可以如下使用:

    if err := ExecSqlWithTransaction(database,sqlQuery,paras...);err != nil{
        //錯誤處理
    }

    封裝后是不是很簡潔啊?

    進一步封裝

    在一個事務中可能會出現多個SELECT、UPDATE等操作,以上封裝僅處理了一種操作,還不能滿足我們的實際需求,因此需要更進一步封裝。

    func ExecSqlWithTransaction(db *sql.DB, handle func(tx *sql.Tx) error) (err error) {
     tx, err := db.Begin()
     if err != nil {
      return err
     }
     defer func() {
      if err != nil {
       tx.Rollback()
      }
     }()
     if err = handle(tx); err != nil {
      return err
     }
     return tx.Commit()
    }

    在handle func內可以直接使用事務tx進行增刪改查。

    以上是“golang中如何實現db事務的統一封裝”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    阿坝县| 武汉市| 安徽省| 威信县| 乌什县| 陆丰市| 郴州市| 绵阳市| 深水埗区| 阳原县| 汾西县| 时尚| 开封市| 固始县| 乐东| 明星| 博野县| 札达县| 明水县| 封开县| 嘉鱼县| 桓仁| 晋城| 麻阳| 遂平县| 开远市| 安平县| 柳江县| 兰坪| 杭锦旗| 五莲县| 丰都县| 肥东县| 南溪县| 浏阳市| 南京市| 关岭| 新乡县| 土默特左旗| 图片| 武平县|