0

0

Go错误处理在数据库操作中的应用_Go SQL错误判断技巧

P粉602998670

P粉602998670

发布时间:2026-01-16 13:36:10

|

815人浏览过

|

来源于php中文网

原创

应使用 errors.Is(err, sql.ErrNoRows) 显式判断查询无数据,而非 err == sql.ErrNoRows 或泛化错误处理;仅 QueryRow/QueryRowContext 返回该错误,Query 需用 rows.Next() 判断。

go错误处理在数据库操作中的应用_go sql错误判断技巧

如何判断 sql.ErrNoRows 而不是泛化地用 errors.Is 捕获所有错误

数据库查询没找到数据时,db.QueryRow().Scan() 会返回 sql.ErrNoRows,这是预期行为,不是异常。直接用 if err != nil 判定会导致误报业务错误。

  • 必须用 errors.Is(err, sql.ErrNoRows) 显式识别,不能用 err == sql.ErrNoRows —— 因为底层可能包装过
  • 若想忽略“无数据”并返回零值,可直接写 if errors.Is(err, sql.ErrNoRows) { return 0, nil }
  • 注意:只有 QueryRowQueryRowContext 会返回 sql.ErrNoRowsQuery 返回空 *sql.Rows,需靠 rows.Next() 判断

driver.ErrBadConn 的真实用途与过时风险

这个错误曾用于提示连接失效,让调用方重试。但自 Go 1.8 起,database/sql 已内置连接健康检查和自动重试逻辑,driver.ErrBadConn 不再被上层识别为重试信号。

  • 现代驱动(如 pgxmysql)已弃用该错误;若你还在代码里手动判断它,大概率是旧文档或遗留逻辑
  • 真正需要重试的场景(如网络闪断),应依赖 context.WithTimeout + 外层重试控制,而非解析底层驱动错误
  • 如果驱动仍返回 driver.ErrBadConn,建议升级驱动版本,或改用 errors.Is(err, driver.ErrBadConn) 后直接记录日志,不再做恢复动作

事务中遇到 sql.ErrTxDone 怎么办

调用 tx.Commit()tx.Rollback() 后,该事务对象即进入完成状态。后续再对它执行 tx.Querytx.Exec 就会返回 sql.ErrTxDone —— 这是明确的使用错误,不是并发问题。

HeyGen
HeyGen

HeyGen是一个AI虚拟数字人生成平台,可以根据用户提供的内容,快速生成高质量的虚拟发言人视频,支持数字化身、文本转视频和视频翻译。

下载
  • 常见诱因:defer 中写了 tx.Rollback(),但前面已显式 Commit(),导致重复操作
  • 正确模式是用 if tx == nil 或标志位控制 rollback 是否执行,或者统一用 defer func() { if r := recover(); r == nil && !committed { _ = tx.Rollback() } }()
  • 不要试图恢复 sql.ErrTxDone,它表示你已经失去了对该事务的控制权,必须新建事务重试
func updateUser(tx *sql.Tx, id int, name string) error {
	_, err := tx.Exec("UPDATE users SET name = ? WHERE id = ?", name, id)
	if err != nil {
		return err
	}
	// 此处若误加 tx.Rollback(),下次再调用 tx.Exec 就会触发 sql.ErrTxDone
	return nil
}

为什么 errors.As 在数据库错误中很少用得上

errors.As 用于提取底层错误类型(比如把包装后的错误转成 *pq.Error),但它只在你需要读取数据库特有字段(如 PostgreSQL 的 CodeDetail)时才有意义。多数业务层只需分类处理,不需要深入驱动细节。

  • PostgreSQL 场景下,若要区分唯一约束冲突(23505)和外键失败(23503),才需 errors.As(err, &pqErr)
  • MySQL 驱动目前不导出错误结构体,errors.As 无法提取具体 SQLSTATE,只能靠 err.Error() 字符串匹配(不推荐)
  • 跨数据库项目应避免依赖驱动特定错误,优先用 errors.Is 判断通用语义错误(如 sql.ErrNoRowssql.ErrTxDone
实际写业务逻辑时,最容易被忽略的是:**错误是否真的需要传播出去**。比如一个用户资料查询接口,查不到就该返回 404;但同一个错误若出现在订单创建的关联校验里,可能就得回滚整个事务。错误语义必须和上下文强绑定,而不是统一塞进 log.Fatal 或往上 panic。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

678

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

320

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

346

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1095

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

357

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

675

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

573

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

415

2024.04.29

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

3

2026.01.16

热门下载

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

精品课程

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

共48课时 | 1.8万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 793人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号