亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

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

    尼玛县| 松滋市| 西畴县| 包头市| 胶州市| 宁都县| 辛集市| 秦皇岛市| 同仁县| 原阳县| 平陆县| 斗六市| 平罗县| 桐乡市| 德庆县| 精河县| 东辽县| 元谋县| 台南市| 淅川县| 阳江市| 祁阳县| 保定市| 青浦区| 泰安市| 滨州市| 沙坪坝区| 霸州市| 介休市| 安泽县| 留坝县| 永德县| 沾化县| 克东县| 阿尔山市| 五家渠市| 红原县| 巴里| 嘉峪关市| 忻城县| 新巴尔虎左旗|