讲师中心 微信公众号

工具推荐

视频效率加速
Laper
Laper

剧本策划到成片协作

updream

一键生成高质量推广成片

Seko
Seko

AI短剧一键生成成片

剧云
剧云

中文短剧剧本制作平台

Golang数据库操作中的错误处理策略

落枫姑娘_2660

落枫姑娘_2660

发布时间:2026-01-12 17:06:53

|

253人浏览过

|

来源于php中文网

原创

Go中database/sql错误判断需区分sql.ErrNoRows等预期错误与其他系统错误,事务Rollback()必须检查返回值,context超时错误应归类为临时故障,自定义错误类型比字符串匹配更可靠。

golang数据库操作中的错误处理策略

Go 中 database/sql 的错误判断不能只看 err != nil

很多刚写 Go 数据库逻辑的人会直接写 if err != nil 就 panic 或返回,但这样会漏掉关键状态:比如查询无结果、连接断开、事务已提交失败等。Go 的 database/sql 包把“业务无数据”和“系统出错”都塞进 error 接口,必须区分。

  • sql.ErrNoRows 是唯一可预期的“非错误错误”,表示 QueryRow 没查到任何行 —— 它不是 bug,通常该走空值逻辑(如赋默认值或返回零结构)
  • 其他错误(如 driver: bad connection、context deadline exceeded)才需要重试、记录或中断流程
  • 别用 errors.Is(err, sql.ErrNoRows) 判断后还继续用扫描变量,因为 Scan() 本身已失败,变量未被赋值

事务中遇到错误时,tx.Rollback() 必须检查其返回值

tx.Rollback() 不是“一定会成功”的兜底操作 —— 如果事务早已因网络中断、数据库崩溃或超时被服务端自动清理,再次调用 Rollback() 可能返回新错误(如 sql: transaction has already been committed or rolled back)。忽略它会导致误判事务状态。

  • 总要像处理主逻辑一样处理 Rollback() 的 error:
    if err := tx.Rollback(); err != nil && !errors.Is(err, sql.ErrTxDone) {
        log.Printf("rollback failed: %v", err)
    }
  • sql.ErrTxDone 是唯一可安全忽略的 rollback 错误,表示事务确实已经结束(无论 commit 还是 rollback)
  • 不要在 defer 中无条件调用 tx.Rollback(),除非你明确知道事务还没 commit,否则可能覆盖真正的 commit 结果

使用 context.Context 控制查询生命周期,但注意驱动兼容性

传入 ctx 是防止查询卡死的最有效方式,但不同驱动对 context 的支持程度不一。比如 mysql 驱动从 v1.7+ 才完整支持 cancel;postgres 的 pgx 默认支持,但原生 lib/pq 已归档且部分 context 行为不一致。

win可用的mysql指令skill
win可用的mysql指令skill

安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。

下载
  • 用 db.QueryContext(ctx, ...) 替代 db.Query(...),并确保 ctx 带 timeout:
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    rows, err := db.QueryContext(ctx, "SELECT * FROM users WHERE id = $1", id)
  • 若 ctx 超时,错误通常是 context deadline exceeded 或驱动特有提示(如 MySQL: driver: query canceled due to context deadline),这类错误应归类为临时故障,适合重试
  • SQLite 驱动(如 mattn/go-sqlite3)不响应 cancel,context 在那里只是摆设,需靠语句级 timeout(如 PRAGMA busy_timeout)补位

自定义错误类型比字符串匹配更可靠

用 strings.Contains(err.Error(), "duplicate key") 判断唯一约束冲突,既脆弱又难维护 —— 字段名、驱动版本、语言环境都可能导致错误信息变化。应该把数据库错误映射到应用层语义错误。

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

  • PostgreSQL 错误码(如 23505)稳定,可用 pgx 的 pgconn.PgError 提取:
    var pgErr *pgconn.PgError
    if errors.As(err, &pgErr) && pgErr.Code == "23505" {
        return ErrDuplicateEmail
    }
  • MySQL 错误号(如 1062)也可通过 mysql.MySQLError 类型断言获取,比字符串安全得多
  • 所有数据库错误最终应转成你应用定义的错误变量(如 ErrNotFound、ErrConflict),上层不用关心底层驱动细节

实际项目里最容易被跳过的,是 rollback 后对错误的再判断,以及把 SQL 层错误硬编码进业务分支。这两处一旦出问题,日志看不出原因,监控也抓不到异常路径。

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

539

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

616

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1296

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

811

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1886

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

5394

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

2514

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

4346

2025.06.17

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

0

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 196人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn