Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
Golang 中优雅地处理数据库事务:自动 Commit 或 Rollback_创想鸟

Golang 中优雅地处理数据库事务:自动 Commit 或 Rollback

golang 中优雅地处理数据库事务:自动 commit 或 rollback

本文旨在提供一种简洁高效的 Golang 数据库事务处理方式,避免手动追踪事务状态。通过封装事务处理逻辑,可以确保事务在出现错误时自动回滚,成功时自动提交,并优雅地处理潜在的 panic 情况,从而提高代码的可读性和健壮性。

在 Golang 中使用 database/sql 包处理数据库事务时,手动管理 Commit 和 Rollback 可能会变得繁琐且容易出错。尤其是在复杂的业务逻辑中,需要多次执行数据库操作,并确保在任何错误发生时都能够正确回滚事务。一种常见的做法是使用 defer 语句来确保事务最终被提交或回滚。

传统的事务处理方式

以下是一个常见的事务处理模式:

func (s Service) DoSomething() (err error) {    tx, err := s.db.Begin()    if err != nil {        return    }    defer func() {        if err != nil {            tx.Rollback()            return        }        err = tx.Commit()    }()    if _, err = tx.Exec(...); err != nil {        return    }    if _, err = tx.Exec(...); err != nil {        return    }    // ...    return}

这种方式虽然可行,但存在一些问题:

立即学习“go语言免费学习笔记(深入)”;

代码重复: 每个需要事务的函数都需要重复这段逻辑。可读性差: 事务处理逻辑与业务逻辑混杂在一起,降低了代码的可读性。容易出错: 如果忘记在 defer 中处理 Rollback,或者在其他地方错误地修改了 err 变量,可能会导致事务处理不正确。

使用事务处理 Handler 简化事务管理

为了解决上述问题,可以创建一个通用的事务处理 Handler,将事务的 Begin、Commit 和 Rollback 逻辑封装起来。

Shakker Shakker

多功能AI图像生成和编辑平台

Shakker 103 查看详情 Shakker

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() // err is non-nil; don't change it        } else {            err = tx.Commit() // err is nil; if Commit returns error update err        }    }()    err = txFunc(tx)    return err}

这个 Transact 函数接收一个 sql.DB 对象和一个函数 txFunc 作为参数。txFunc 接收一个 sql.Tx 对象作为参数,并在其中执行实际的数据库操作。

Transact 函数的主要逻辑如下:

开启事务: 使用 db.Begin() 开启一个新的事务。Defer 处理: 使用 defer 语句定义一个匿名函数,该函数将在 Transact 函数返回之前执行。Panic 处理: 在 defer 函数中使用 recover() 捕获任何 panic。如果发生 panic,则回滚事务并重新抛出 panic,以便上层调用者可以处理。错误处理: 如果 txFunc 返回一个非空的错误,则回滚事务。提交事务: 如果 txFunc 没有返回错误,则提交事务。执行 txFunc: 调用 txFunc 执行实际的数据库操作。

使用事务处理 Handler

使用 Transact 函数可以大大简化事务处理的代码:

func (s Service) DoSomething() error {    return Transact(s.db, func(tx *sql.Tx) error {        if _, err := tx.Exec(...); err != nil {            return err        }        if _, err := tx.Exec(...); err != nil {            return err        }        return nil    })}

可以看到,使用 Transact 函数后,DoSomething 函数的代码变得更加简洁和易读。所有事务处理的细节都被隐藏在 Transact 函数中,业务逻辑更加清晰。

注意事项

Panic 处理: 在 Transact 函数中,使用 recover() 捕获 panic 并重新抛出。这可以确保在发生 panic 时,事务能够被正确回滚,并且 panic 能够被上层调用者处理。错误处理: 在 defer 函数中,只有在 err 为 nil 时才会调用 tx.Commit()。这是因为如果 txFunc 返回了一个错误,则不需要再次调用 tx.Commit()。Return Value: 注意 defer 语句可以修改闭包中捕获的返回值。因此,在 Transact 函数中,使用 err = tx.Commit() 将 tx.Commit() 的返回值赋值给 err,以便将提交事务时可能发生的错误传递给上层调用者。

总结

通过使用事务处理 Handler,可以有效地简化 Golang 中的数据库事务管理。这种方式可以提高代码的可读性、可维护性和健壮性,并减少出错的可能性。建议在所有需要事务处理的场景中使用这种模式。

以上就是Golang 中优雅地处理数据库事务:自动 Commit 或 Rollback的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1136261.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
《梦幻西游》拒绝当沙包!教你如何跻进阵营前20%,轻轻松松收获3000W经验
上一篇 2025年12月2日 17:53:12
Redis实现秒杀的方法介绍(附代码)
下一篇 2025年12月2日 17:53:21

相关推荐

  • 使用 JavaScript 验证后调用 Servlet 的正确方法

    使用 JavaScript 验证后调用 Servlet 的正确方法使用 JavaScript 验证后调用 Servlet 的正确方法使用 JavaScript 验证后调用 Servlet 的正确方法使用 JavaScript 验证后调用 Servlet 的正确方法

    本文档旨在指导开发者如何在 JavaScript 验证客户端输入后,正确地调用 Servlet 来处理表单数据。我们将重点关注如何避免常见的 HTTP 405 错误,并提供清晰的代码示例和最佳实践,确保数据安全可靠地传输到服务器。 在 Web 开发中,客户端验证通常用于在数据提交到服务器之前检查其有…

    2026年9月28日 • 用户投稿
    100
  • Android应用开发:使用Intent实现页面跳转

    Android应用开发:使用Intent实现页面跳转Android应用开发:使用Intent实现页面跳转Android应用开发:使用Intent实现页面跳转Android应用开发:使用Intent实现页面跳转

    本文将介绍如何在Android应用中实现页面之间的跳转。通过使用Intent,我们可以轻松地从一个Activity切换到另一个Activity。本文将提供示例代码和详细步骤,帮助你理解Intent的基本用法,并掌握在按钮点击事件中启动新Activity的方法。 在Android应用开发中,页面跳转是…

    2026年9月28日 • 用户投稿
    000
  • 格子达论文查重怎么操作_格子达官方检测系统指南

    格子达论文查重怎么操作_格子达官方检测系统指南格子达论文查重怎么操作_格子达官方检测系统指南格子达论文查重怎么操作_格子达官方检测系统指南格子达论文查重怎么操作_格子达官方检测系统指南

    首先登录格子达官网注册账号并登录,接着在个人中心上传符合格式的论文文件,填写必要信息后提交检测,最后等待系统生成报告并下载查看总相似比、AI占比等数据,结合标注内容进行修改。 格子达论文查重怎么操作?这是不少网友都关注的,接下来由PHP小编为大家带来格子达官方检测系统指南,感兴趣的网友一起随小编来瞧…

    2026年9月28日 • 用户投稿
    000
  • Android 应用中页面(Activity)间导航的实现指南

    Android 应用中页面(Activity)间导航的实现指南Android 应用中页面(Activity)间导航的实现指南Android 应用中页面(Activity)间导航的实现指南Android 应用中页面(Activity)间导航的实现指南

    本文详细介绍了在 Android 应用中如何通过按钮实现不同页面(Activity)之间的切换。核心机制是使用 Intent 对象来指定目标 Activity,并通过 startActivity() 方法启动它。文章提供了 MainActivity.java 中的示例代码,并强调了 AndroidM…

    2026年9月28日 • 用户投稿
    000
  • sublime怎么显示函数列表_Sublime Text快速跳转到函数或符号定义

    sublime怎么显示函数列表_Sublime Text快速跳转到函数或符号定义sublime怎么显示函数列表_Sublime Text快速跳转到函数或符号定义sublime怎么显示函数列表_Sublime Text快速跳转到函数或符号定义sublime怎么显示函数列表_Sublime Text快速跳转到函数或符号定义

    使用Ctrl+R或Cmd+R调用内置符号跳转功能,可快速定位当前文件的函数、类等定义;通过安装CTags、Symbol Browser或SublimeCodeIntel等插件,能实现跨文件跳转与更精准识别;配合LSP插件启用Goto Definition(F12),可获得类似IDE的智能跳转体验,显…

    2026年9月28日 • 用户投稿
    400
  • win11自带的视频编辑器在哪里 win11自带视频编辑器打开与使用方法

    win11自带的视频编辑器在哪里 win11自带视频编辑器打开与使用方法win11自带的视频编辑器在哪里 win11自带视频编辑器打开与使用方法win11自带的视频编辑器在哪里 win11自带视频编辑器打开与使用方法win11自带的视频编辑器在哪里 win11自带视频编辑器打开与使用方法

    Windows 11用户可通过五种方式使用Clipchamp编辑视频:1. 从开始菜单点击应用启动;2. 使用Win+S搜索并打开;3. 在“照片”应用中选择视频后创建项目跳转;4. 右键视频文件选择“使用Clipchamp编辑”;5. 通过浏览器访问官网在线登录使用。 如果您需要对视频进行剪辑、添…

    2026年9月28日 • 用户投稿
    1000
  • firefox浏览器为什么打不开某些网站 Firefox浏览器特定网站访问失败排查方案

    firefox浏览器为什么打不开某些网站 Firefox浏览器特定网站访问失败排查方案firefox浏览器为什么打不开某些网站 Firefox浏览器特定网站访问失败排查方案firefox浏览器为什么打不开某些网站 Firefox浏览器特定网站访问失败排查方案firefox浏览器为什么打不开某些网站 Firefox浏览器特定网站访问失败排查方案

    清除缓存和Cookie;2. 确保JavaScript启用;3. 禁用硬件加速;4. 刷新Firefox;5. 修改DNS为8.8.8.8/8.8.4.4,可解决Firefox无法加载网页问题。 如果您尝试访问某个网站,但Firefox浏览器无法加载页面或显示异常,则可能是由于网络设置、浏览器配置或…

    2026年9月28日 • 用户投稿
    100
  • windows怎么设置从u盘启动_设置U盘为第一启动项教程

    windows怎么设置从u盘启动_设置U盘为第一启动项教程windows怎么设置从u盘启动_设置U盘为第一启动项教程windows怎么设置从u盘启动_设置U盘为第一启动项教程windows怎么设置从u盘启动_设置U盘为第一启动项教程

    首先调整BIOS/UEFI启动顺序,将U盘设为第一启动项,具体步骤包括进入设置界面、切换至启动选项卡、识别并上移U盘设备、保存配置后重启,或通过快捷键临时选择U盘启动。 如果您需要在Windows电脑上安装操作系统或进行系统维护,但计算机默认从硬盘启动导致无法进入U盘引导界面,您需要调整BIOS/U…

    2026年9月27日 • 用户投稿
    100
  • win8怎么安装chrome浏览器_Win8安装Chrome浏览器教程

    win8怎么安装chrome浏览器_Win8安装Chrome浏览器教程win8怎么安装chrome浏览器_Win8安装Chrome浏览器教程win8怎么安装chrome浏览器_Win8安装Chrome浏览器教程win8怎么安装chrome浏览器_Win8安装Chrome浏览器教程

    首先尝试通过官网在线下载安装Chrome,若失败则使用离线安装包,最后可采用命令行静默安装解决Windows 8系统无法安装Chrome的问题。 如果您尝试在Windows 8系统上安装Chrome浏览器,但遇到无法下载或安装失败的情况,可能是由于网络问题、系统兼容性或安装源受限所致。以下是解决此问…

    2026年9月27日 • 用户投稿
    100
  • sublime怎么配置java语法检查_sublime Java语法检查配置

    sublime怎么配置java语法检查_sublime Java语法检查配置sublime怎么配置java语法检查_sublime Java语法检查配置sublime怎么配置java语法检查_sublime Java语法检查配置sublime怎么配置java语法检查_sublime Java语法检查配置

    首先安装Package Control,再通过它安装SublimeLinter和SublimeLinter-javac插件,确保系统已配置JDK并能全局运行javac,最后在SublimeLinter设置中启用javac,即可实现Java语法检查。 Sublime Text 本身不自带 Java 语…

    2026年9月27日 • 用户投稿
    1100
  • 高通:95%的用户愿为搭载骁龙心片的高端手机溢价买单

    高通:95%的用户愿为搭载骁龙心片的高端手机溢价买单高通:95%的用户愿为搭载骁龙心片的高端手机溢价买单高通:95%的用户愿为搭载骁龙心片的高端手机溢价买单高通:95%的用户愿为搭载骁龙心片的高端手机溢价买单

    在骁龙峰会2025上,高通高级副总裁don mcguire表示,最新调研显示,84%的消费者认为搭载骁龙处理器的笔记本表现出色,具备强大性能;同时,95%的用户愿意为配备骁龙移动平台的高端智能手机支付更高价格。 据CNMO了解,骁龙品牌在多个市场已展现出强劲影响力。根据CyberMedia Rese…

    2026年9月27日 • 用户投稿
    100
  • 外网博主对《失落之魂》十分看好:有望竞争年度最佳

    外网博主对《失落之魂》十分看好:有望竞争年度最佳外网博主对《失落之魂》十分看好:有望竞争年度最佳外网博主对《失落之魂》十分看好:有望竞争年度最佳外网博主对《失落之魂》十分看好:有望竞争年度最佳

    由国内独立开发者杨冰领衔打造、备受瞩目的动作游戏《失落之魂》(Lost Soul Aside)即将在本月底正式发售,引发全球玩家高度关注。 近日,海外知名游戏实况主Dannozdirect Gaming发布了一段深度解析视频,对这款自2016年启动开发的作品给予了极高评价,甚至认为它具备角逐“年度最…

    2026年9月27日 • 用户投稿
    100
  • 360极速浏览器怎么把网页保存为图片_360极速浏览器网页长截图与另存为图片功能

    360极速浏览器怎么把网页保存为图片_360极速浏览器网页长截图与另存为图片功能360极速浏览器怎么把网页保存为图片_360极速浏览器网页长截图与另存为图片功能360极速浏览器怎么把网页保存为图片_360极速浏览器网页长截图与另存为图片功能360极速浏览器怎么把网页保存为图片_360极速浏览器网页长截图与另存为图片功能

    首先使用360极速浏览器内置长截图功能,点击菜单中“网页截图”选择“长截图”自动捕获全页并保存为PNG;其次可右键查看是否有“将页面另存为图片”选项直接导出JPEG或PNG格式;最后当功能受限时,通过扩展中心安装“FireShot”等插件实现高清全页截图并下载。 如果您希望将浏览的网页完整保存为图片…

    2026年9月27日 • 用户投稿
    100
  • 使用 GSON 和 Kotlin 泛型将 JSON 转换为自定义类

    使用 GSON 和 Kotlin 泛型将 JSON 转换为自定义类使用 GSON 和 Kotlin 泛型将 JSON 转换为自定义类使用 GSON 和 Kotlin 泛型将 JSON 转换为自定义类使用 GSON 和 Kotlin 泛型将 JSON 转换为自定义类

    本文档旨在解决在使用 GSON 和 Kotlin 泛型进行 JSON 反序列化时,将 JSON 数据转换为自定义类时遇到的 ClassCastException 问题。通过分析问题原因,提供解决方案,并介绍未来 GSON 版本中对此类问题的改进,帮助开发者更好地理解和使用 GSON 进行 Kotli…

    2026年9月27日 • 用户投稿
    100
  • 解决Kotlin中Gson与Reified泛型结合时的类型转换异常

    解决Kotlin中Gson与Reified泛型结合时的类型转换异常解决Kotlin中Gson与Reified泛型结合时的类型转换异常解决Kotlin中Gson与Reified泛型结合时的类型转换异常解决Kotlin中Gson与Reified泛型结合时的类型转换异常

    在kotlin开发中,结合gson库处理泛型数据反序列化是常见的场景。kotlin的reified泛型特性为我们提供了在运行时访问泛型类型信息的能力,这在与java互操作(如使用gson)时显得尤为重要。然而,如果未能正确理解和应用reified,便可能遭遇java.lang.classcastex…

    2026年9月27日 • 用户投稿
    100
  • windows怎么进入bios设置_进入BIOS设置操作指南

    windows怎么进入bios设置_进入BIOS设置操作指南windows怎么进入bios设置_进入BIOS设置操作指南windows怎么进入bios设置_进入BIOS设置操作指南windows怎么进入bios设置_进入BIOS设置操作指南

    进入BIOS的方法包括:通过电源菜单按Shift+重启进入UEFI设置;2. 通过系统设置中的恢复选项启动至UEFI固件设置;3. 开机时按下F2、F10或Delete等厂商指定功能键;4. 若因快速启动导致按键失效,需先在电源选项中禁用快速启动后再使用功能键进入。 如果您需要调整计算机的硬件配置或…

    2026年9月27日 • 用户投稿
    100
  • 解决Spring REST API 406 Not Acceptable错误

    解决Spring REST API 406 Not Acceptable错误解决Spring REST API 406 Not Acceptable错误解决Spring REST API 406 Not Acceptable错误解决Spring REST API 406 Not Acceptable错误

    本文旨在帮助开发者解决在使用Spring REST API时遇到的“406 Not Acceptable”错误。该错误通常表示服务器无法找到客户端可接受的表示形式。我们将详细介绍错误的原因、解决方案,并通过示例代码演示如何配置produces属性来指定API的响应类型,确保客户端能够正确接收和处理数…

    2026年9月27日 • 用户投稿
    100
  • AI绘画工具生成的图片可以商用吗?2025解析

    AI绘画图片能否商用取决于工具版权政策和使用方式。首先需查看所用AI工具的服务条款:若明确赋予用户商业使用权,则可放心商用;若限制商用或版权归开发者,则存在法律风险。为规避风险,应选择版权政策宽松的工具,对生成图片进行二次创作以增强独创性,并保留生成记录作为证据。用于品牌Logo时更需谨慎,因AI生…

    2026年9月27日
    200
  • 宏碁非凡 Go Air 超轻薄本发布,轻便耐用性能强

    宏碁非凡 Go Air 超轻薄本发布,轻便耐用性能强宏碁非凡 Go Air 超轻薄本发布,轻便耐用性能强宏碁非凡 Go Air 超轻薄本发布,轻便耐用性能强宏碁非凡 Go Air 超轻薄本发布,轻便耐用性能强

    宏碁非凡go air超轻薄本惊艳上市,仅重999克,售价4999元,首发更享国家补贴,到手价仅需3999.2元!这款轻薄本采用镁铝合金机身,搭配时尚的星辰灰配色,兼顾轻便与耐用性。 性能方面,非凡Go Air搭载强劲的英特尔酷睿i7-13260H处理器,拥有10核16线程,最高睿频可达4.9GHz,…

    2026年9月27日 • 用户投稿
    100
  • 获取父级 Option Group 的文本标签

    获取父级 Option Group 的文本标签获取父级 Option Group 的文本标签获取父级 Option Group 的文本标签获取父级 Option Group 的文本标签

    本文介绍了如何使用 JavaScript 获取 HTML 元素中选定 标签的父级 标签的文本标签。重点在于理解 closest() 方法的行为,以及嵌套 标签可能带来的问题,并提供替代方案以实现所需功能。 理解 closest() 方法 在 JavaScript 中,closest() 方法用于查找…

    2026年9月27日 • 用户投稿
    100

发表回复

登录后才能评论
关注微信