golang sql 中的transaction(事务)的用法

golang_china · 2016-03-02 16:26:39 · 9799 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2016-03-02 16:26:39 的主题,其中的信息可能已经有所发展或是发生改变。

事务就是 保证不同的sql 语句同时成功,或者同时失败的方法。基础用法就不说了,我发现很多人在执行事务 commit , rollback的时候 并不判断是否成功或者失败,也不记录日志。这个虽然说有一点点难度,但是还是非常好做的,可能大家都受到官网文档误导了。 官网文档用的时候就不判断错误,不判断错误如果rollback出错了,没日志,定位会很难,数据不一致问题也非常严重,真是误人子弟!

package main                                                                                                     

import (
    "database/sql"

    "x/log.v7"
)

func logRollback(tx *sql.Tx) {
    err := tx.Rollback()
    if err != tx.ErrTxDone && err != nil {
        log.Error()
    }
}


func main() {
    tx, err := sql.DB.Begin()
    if err != nil {
        log.Error()
        return
    }
    defer logRollback(tx) // 此处必须用defer, defer 很多人理解为怕忘记了,先写上,其实defer真正的作用是无论如何都能执行到,即使 panic,当然如果在 defer 函数前就panic得情况下,也是没办法执行的。我当初也理解错defer了。也是因为这个原因我想很多人就不记录日志了吧。其实也能用defer func,都可以,记录错误就可以

    if result, err := tx.Exec(query1); err != nil {
        log.Error()
        return
    }
    doSomething()
    if row, err := tx.Query(query2); err != nil {
        log.Error()      // 此处调用 rollback 是不对的, 因为在 doSomething 可能panic,这样 rollback就执行不到了,所以上面必须用defer
        return
    }

    if err := tx.Commit(); err != nil {
        log.Error()
        return
    }
}

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

9799 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传