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运维】欢迎添加关注!文章转载请注明出处。
审核编辑:汤梓红


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

    关注

    126

    文章

    7775

    浏览量

    142712
  • 程序
    +关注

    关注

    116

    文章

    3775

    浏览量

    80839
  • 函数
    +关注

    关注

    3

    文章

    4304

    浏览量

    62423

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

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

收藏 人收藏

    评论

    相关推荐

    【科普】三种电磁屏蔽的目的及原理详解

    电磁屏蔽一般可分为三种:静电屏蔽、静磁屏蔽和高频电磁场屏蔽。三种屏蔽的目的都是防止外界的电磁场进入到某个需要保护的区域中,原理都是利用屏蔽对外场的感应产生的效应来抵消外场的影响。但是由于所要屏蔽的场的特性不同,因而对屏蔽壳材料的要求和屏蔽效果也就不相同。
    发表于 09-29 11:21 4.5w次阅读
    【科普】<b class='flag-5'>三种</b>电磁屏蔽的目的及原理<b class='flag-5'>详解</b>

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

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

    常见三种接口详解

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

    Spring事务管理详解说明

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

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

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

    STM32的三种boot模式介绍

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

    半导体极管的三种基本放大电路的三种连接法电路图

    半导体极管的三种基本放大电路的三种连接法电路图
    发表于 05-06 14:55 5576次阅读
    半导体<b class='flag-5'>三</b>极管的<b class='flag-5'>三种</b>基本放大电路的<b class='flag-5'>三种</b>连接法电路图

    三种投影机散热技术是哪三种

    三种投影机散热技术是哪三种 如今在日常的学习、工作、生活中,投影机的应用越来越频繁。由于投影机属于高
    发表于 02-06 10:33 561次阅读

    三种不同的“防 Ping”技巧

    三种不同的“防 Ping”技巧 浅析三种不同的“防 Ping”方法   众所周知,Ping命令是一个非常有用的网络命令,大家常用它
    发表于 04-14 13:53 1121次阅读

    三种zigbee网络架构详解

    在万物互联的背景下,zigbee网络应用越加广泛,zigbee技术具有强大的组网能力,可以形成星型、树型和网状网,三种zigbee网络结构各有优势,可以根据实际项目需要来选择合适的zigbee网络结构。
    发表于 07-28 16:02 5.2w次阅读
    <b class='flag-5'>三种</b>zigbee网络架构<b class='flag-5'>详解</b>

    浅析单片机三种应用程序的架构

    在工作中经过摸索实验,总结出单片机大致应用程序的架构有三种: 1. 简单的前后台顺序执行程序,这类写法是大多
    的头像 发表于 04-07 09:44 4412次阅读

    PCB常见的三种钻孔详解资料下载

    电子发烧友网为你提供PCB常见的三种钻孔详解资料下载的电子资料下载,更有其他相关的电路图、源代码、课件教程、中文资料、英文资料、参考设计、用户指南、解决方案等资料,希望可以帮助到广大的电子工程师们。
    发表于 04-18 08:45 22次下载
    PCB常见的<b class='flag-5'>三种</b>钻孔<b class='flag-5'>详解</b>资料下载

    MySQL三种日志讲解

    MySQL 日志包含了错误日志、查询日志、慢查询日志、事务日志、二进制日志等,如果存储引擎使用的是 InnoDB ,二进制日志(binlog)和事务日志(包括redo log和undo log) 是肯定绕不过去的,本篇接下来详细为大家介绍这
    的头像 发表于 07-25 11:15 716次阅读
    MySQL<b class='flag-5'>三种</b>日志讲解

    insertinto语句的三种写法

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

    insert into 语句的三种写法

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