您现在的位置是:亿华云 > IT科技类资讯
Golang transaction 事务使用的正确姿势
亿华云2025-10-08 20:55:13【IT科技类资讯】3人已围观
简介本文中作者展示了golang事务的三种写法。第一种写法这种写法非常朴实,程序流程也非常明确,但是事务处理与程序流程嵌入太深,容易遗漏,造成严重的问题funcDoSomething()(errerror
本文中作者展示了 golang 事务的正确姿势三种写法。
第一种写法
这种写法非常朴实,正确姿势程序流程也非常明确,正确姿势但是正确姿势事务处理与程序流程嵌入太深,容易遗漏,正确姿势造成严重的正确姿势问题
func DoSomething() (err error) {
tx, err := db.Begin()
if err != nil {
return
}
defer func() {
if p := recover(); p != nil {
tx.Rollback()
panic(p) // re-throw panic after Rollback
}
}()
if _, err = tx.Exec(...); err != nil {
tx.Rollback()
return
}
if _, err = tx.Exec(...); err != nil {
tx.Rollback()
return
}
// ...
err = tx.Commit()
return
}
第二种写法
下面这种写法把事务处理从程序流程抽离了出来,不容易遗漏,正确姿势但是正确姿势作用域是整个函数,香港云服务器程序流程不是正确姿势很清晰
func DoSomething() (err error) {
tx, err := db.Begin()
if err != nil {
return
}
defer func() {
if p := recover(); p != nil {
tx.Rollback()
panic(p) // re-throw panic after Rollback
} else if err != nil {
tx.Rollback()
} else {
err = tx.Commit()
}
}()
if _, err = tx.Exec(...); err != nil {
return
}
if _, err = tx.Exec(...); err != nil {
return
}
// ...
return
}
第三种写法
写法三是对写法二的进一步封装,写法高级一点,正确姿势缺点同上
func Transact(db *sql.DB,正确姿势 txFunc func(*sql.Tx) error) (err error) {
tx, err := db.Begin()
if err != nil {
return
}
defer func() {
if p := recover(); p != nil {
tx.Rollback()
panic(p) // re-throw panic after Rollback
} else if err != nil {
tx.Rollback()
} else {
err = tx.Commit()
}
}()
err = txFunc(tx)
return err
}
func DoSomething() error {
return Transact(db, func (tx *sql.Tx) error {
if _, err := tx.Exec(...); err != nil {
return err
}
if _, err := tx.Exec(...); err != nil {
return err
}
})
}
我的写法
经过总结和实验,我采用了下面这种写法,正确姿势defer tx.Rollback() 使得事务回滚始终得到执行。正确姿势当 tx.Commit() 执行后,正确姿势tx.Rollback() 起到关闭事务的正确姿势作用,站群服务器 当程序因为某个错误中止,tx.Rollback() 起到回滚事务,同事关闭事务的作用。
普通场景
func DoSomething() (err error) {
tx, _ := db.Begin()
defer tx.Rollback()
if _, err = tx.Exec(...); err != nil {
return
}
if _, err = tx.Exec(...); err != nil {
return
}
// ...
err = tx.Commit()
return
}
循环场景
(1) 小事务 每次循环提交一次 在循环内部使用这种写法的时候,defer 不能使用,所以要把事务部分抽离到独立的函数当中
func DoSomething() (err error) {
tx, _ := db.Begin()
defer tx.Rollback()
if _, err = tx.Exec(...); err != nil {
return
}
if _, err = tx.Exec(...); err != nil {
return
}
// ...
err = tx.Commit()
return
}
for {
if err := DoSomething(); err != nil{
// ...
}
}
(2) 大事务 批量提交 大事务的场景和普通场景是一样的,亿华云没有任何区别
func DoSomething() (err error) {
tx, _ := db.Begin()
defer tx.Rollback()
for{
if _, err = tx.Exec(...); err != nil {
return
}
if _, err = tx.Exec(...); err != nil {
return
}
// ...
}
err = tx.Commit()
return
}
很赞哦!(348)
相关文章
- 只要我们做的是从目前的市场情况选择域名,从简单易记,从个性特征上,我们就可以找到一个好域名进行注册。域名注册进行域名记录和解析以及绑定网站后,客户可以通过URL登录您的网站。
- Vue3.0新特性以及使用经验总结
- CSS3 3D 行星运转 && 浏览器渲染原理
- Java对象竟然会在栈上分配内存?
- 懵了!女朋友突然问我MVCC实现原理
- 如何写出有效的单元测试
- 解构VR:虚拟现实技术如何在情感与道德上影响社会?
- a、变更前的公司证件扫描件(代码证或者营业执照)及联系人身份证复印件、变更后的公司证件扫描件(代码证或者营业执照)及新的联系人身份证复印件;身份证复印件需本人签名,公司证件复印件需加盖公章。
- 针对自动化测试的 23 种 Node.js 优秀实践
站长推荐
5、使用企业名称的英文名称作为域名也是国内许多企业选择域名的一种方式,特别适合一些与计算机、网络和通信相关的行业。
vivo前端智能化实践:机器学习在自动网页布局中的应用
经典动态规划:0-1 背包问题
Python运动检测编程实战演练
当投资者经过第二阶段的认真学习之后又充满了信心,认为自己可以在市场上叱咤风云地大干一场了。但没想到“看花容易绣花难”,由于对理论知识不会灵活运用.从而失去灵活应变的本能,就经常会出现小赢大亏的局面,结果往往仍以失败告终。这使投资者很是困惑和痛苦,不知该如何办,甚至开始怀疑这个市场是不是不适合自己。在这种情况下,有的人选择了放弃,但有的意志坚定者则决定做最后的尝试。
异步Python比同步Python快在哪里?
面试突击77:Spring 依赖注入有几种?各有什么优缺点?
详细解读ThreadLocal的内存泄露