0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

详解golang事务的三种写法

马哥Linux运维 来源:CSDN 作者:CSDN 2022-03-16 08:52 次阅读

本文中作者展示了golang事务的三种写法

第一种写法

这种写法非常朴实,程序流程也非常明确,但是事务处理与程序流程嵌入太深,容易遗漏,造成严重的问题

funcDoSomething()(errerror){
tx,err:=db.Begin()
iferr!=nil{
return
}


deferfunc(){
ifp:=recover();p!=nil{
tx.Rollback()
panic(p)//re-throwpanicafterRollback
}
}()


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


err=tx.Commit()
return
}

第二种写法

下面这种写法把事务处理从程序流程抽离了出来,不容易遗漏,但是作用域是整个函数,程序流程不是很清晰

funcDoSomething()(errerror){
tx,err:=db.Begin()
iferr!=nil{
return
}


deferfunc(){
ifp:=recover();p!=nil{
tx.Rollback()
panic(p)//re-throwpanicafterRollback
}elseiferr!=nil{
tx.Rollback()
}else{
err=tx.Commit()
}
}()


if_,err=tx.Exec(...);err!=nil{
return
}
if_,err=tx.Exec(...);err!=nil{
return
}
//...
return
}

第三种写法

写法三是对写法二的进一步封装,写法高级一点,缺点同上

funcTransact(db*sql.DB,txFuncfunc(*sql.Tx)error)(errerror){
tx,err:=db.Begin()
iferr!=nil{
return
}


deferfunc(){
ifp:=recover();p!=nil{
tx.Rollback()
panic(p)//re-throwpanicafterRollback
}elseiferr!=nil{
tx.Rollback()
}else{
err=tx.Commit()
}
}()


err=txFunc(tx)
returnerr
}


funcDoSomething()error{
returnTransact(db,func(tx*sql.Tx)error{
if_,err:=tx.Exec(...);err!=nil{
returnerr
}
if_,err:=tx.Exec(...);err!=nil{
returnerr
}
})
}

我的写法

经过总结和实验,我采用了下面这种写法,defer tx.Rollback() 使得事务回滚始终得到执行。当 tx.Commit() 执行后,tx.Rollback() 起到关闭事务的作用, 当程序因为某个错误中止,tx.Rollback() 起到回滚事务,同事关闭事务的作用。

普通场景

funcDoSomething()(errerror){
tx,_:=db.Begin()
defertx.Rollback()

if_,err=tx.Exec(...);err!=nil{
return
}
if_,err=tx.Exec(...);err!=nil{
return
}
//...


err=tx.Commit()
return
}

循环场景

(1) 小事务 每次循环提交一次 在循环内部使用这种写法的时候,defer 不能使用,所以要把事务部分抽离到独立的函数当中

funcDoSomething()(errerror){
tx,_:=db.Begin()
defertx.Rollback()

if_,err=tx.Exec(...);err!=nil{
return
}
if_,err=tx.Exec(...);err!=nil{
return
}
//...


err=tx.Commit()
return
}


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

(2) 大事务 批量提交 大事务的场景和普通场景是一样的,没有任何区别

funcDoSomething()(errerror){
tx,_:=db.Begin()
defertx.Rollback()

for{
if_,err=tx.Exec(...);err!=nil{
return
}
if_,err=tx.Exec(...);err!=nil{
return
}
//...
}

err=tx.Commit()
return
}

原文标题:Golang transaction 事务使用的正确姿势

文章出处:【微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。
审核编辑:汤梓红


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 封装
    +关注

    关注

    123

    文章

    7270

    浏览量

    141077
  • 程序
    +关注

    关注

    114

    文章

    3630

    浏览量

    79527
  • 函数
    +关注

    关注

    3

    文章

    3865

    浏览量

    61307

原文标题:Golang transaction 事务使用的正确姿势

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    TCPIP详解:TCP事务协议,HTTP,NNTP和UNIX域协议

    TCPIP详解:TCP事务协议,HTTP,NNTP和UNIX域协议
    发表于 09-28 12:45

    无线视频模块的三种传输方式详解

    无线视频模块主要由发射器,接收器和控制器组成,无线视频模块是利用无线技术进行无线传输模块的一模块。它被广泛地应用于无线通讯,视频监控等领域。以下是无线视频模块的三种传输方式的详解:1、无线
    发表于 07-30 09:17

    常见三种接口详解

    做单片机开发时UART,SPI和I2C都是我们最经常使用到的硬件接口,我收集了相关的具体材料对这三种接口进行了详细的解释。
    发表于 08-02 08:13

    Altium Designer三种测量距离方式的区别

    在AD中主要有三种测量距离的方式:Ⅰ:点到点的距离测量,菜单栏命令Reports→MeasureDistance,快捷键为“RM”或Ctrl+M。 如依次点选中两个电阻的焊盘中心,可以测量出这两个焊
    发表于 10-29 14:24

    Spring事务管理详解说明

    Spring事务管理详解
    发表于 05-20 13:46

    启动Spring Boot项目应用的三种方法

    基础。我们知道了Spring Boot是个什么了,那么我们又该如何启动Spring Boot应用呢?这里小编给大家推荐常用的三种方法。分别是IDEA编辑器启动、命令启动、java命令jar文件启动。下面
    发表于 01-14 17:33

    伺服电机的三种控制方式详解

    伺服电机的三种控制方式
    发表于 01-21 06:45

    HarmonyOS实战—Text组件宽高三种值的写法和颜色属性

    最大分辨率如:2K屏就是由宽:1920个小格子和高:1080个小格子组成的手机端的分辨率 2. 宽高三种值的写法2.1 宽高为:match_content 2.2 宽高为:match_parent,铺满
    发表于 08-12 12:31

    STM32有三种启动模式

    01STM32的三种启动模式STM32有三种启动模式:FLASH启动、SRAM启动和系统存储器启动,通常三种启动方式由外部引脚boot0和boot1的电平决定。每个系列boot0和boot1电平对应
    发表于 08-18 07:52

    STM32的三种boot模式介绍

    浅识STM32的三种boot模式文章目录浅识STM32的三种boot模式任务摘要一、认识boot1.三种BOOT模式介绍2.开发BOOT模式选择3.STM32三种启动模式4.
    发表于 12-10 07:46

    STM32的三种Boot模式的差异

    如有错误,欢迎指正,谢谢!目录一、STM32的三种Boot模式的差异二、创建基于MDK创建纯汇编语言的STM32工程模板、汇编基本语法的学习四、编程练习一、STM32的三种Boot模式的差异参考自
    发表于 12-20 07:54

    记录三种DMA模式

    串口模式实现有三种1.普通模式:在主函数中接收函数2.中断模式:产生的不影响主程序运行3. DMA模式:与主函数互不影响,独立运行本文记录三种DMA模式。
    发表于 02-28 07:54

    《TCP-IP详解_卷3_TCP事务协议,HTTP,NNTP

    《TCP-IP详解_卷3_TCP事务协议,HTTP,NNTP和UNIX域协议》
    发表于 03-24 22:42 39次下载

    insertinto语句的三种写法

    插入数据是关系数据库基本的操作之一,它允许用户将数据插入已经创建的表中。在关系数据库中,通过使用INSERT INTO语句可以将数据插入到表中的一个或多个列中。 INSERT INTO语句有三种常见
    的头像 发表于 11-17 15:12 1196次阅读

    insert into 语句的三种写法

    INSERT INTO是MySQL中常用的一种SQL语句,用于将数据插入到表中。此文将详细介绍INSERT INTO语句的三种不同写法及其用途,并提供代码示例和相关解释。 正文: 一、基本插入
    的头像 发表于 11-21 14:18 2793次阅读