Go 数据库操作异常处理

简介: Go 数据库操作异常处理

Go 数据库操作异常处理


插入操作


第一种写法


err := db.Model(&XXX{}).Create(order).Error
 if err != nil {
  logs.CtxError(ctx, "Create XXX failed, err:%v", err.Error())
  return  err
 }


第二种写法


db := db.Model(&XXX{}).Create(order)
 if db.Error != nil {
  logs.CtxError(ctx, "Create XXX failed, err:%v", db.Error)
  return  db.Error
 }


上述两种写法说明:

两种写法都没啥问题,第一种写法, 如果只插入一条数据,可以使用第一种写法简单;第二种写法可以拿到执行的 *DB ,方便后续的 DB 操作


更新操作


db := db.Model(&Voucher{}).Where(whereMap).Updates(updateMap)
if db == nil {
 return 0, errors.New(fmt.Sprintf("UpdateVoucherWithState failed, db is null, jrUid:%s, voucherNo:%s", jrUid, voucherNo))
}
err := db.Error
if err != nil {
 logs.CtxError(ctx, "UpdateXXX failed err:%v", err)
}
if db.RowsAffected != 1{
 logs.CtxWarn(ctx, "UpdateXXX failed RowsAffected:%v", db.RowsAffected)
// TODO 根据业务自身特性单独处理
}


说明:

update 方法将返回执行完之后的 *DB, 需要通过指针对象才能获取正确的 RowAffected


事务处理


tx, txErr = model.BeginTransactionNotShard(ctx)
 if txErr != nil {
  logs.CtxError(ctx, "db BeginTransaction err: %v", txErr)
  return constant.GenRetCode(constant.DBError, txErr.Error())
 }
 defer func() {
  if err := recover(); err != nil {
   logs.CtxError(ctx, "panic:%+v", err)
   tx.Rollback(ctx, tx)
  } else if  err != nil {
   // logs.CtxError
   tx.Rollback()
  }
 }()
 if err := tx.Error; err != nil {
  return err
 }
 if err:= tx.Create(&XXX).Error; err != nil {
      return err 
    }
 return tx.Commit().Error


事务的提交也可能会有 error, 要判断是否正确 commit

需要判断 tx.Error,因为事务的提交可能会有 error

查询的异常处理


if err := db.Where("name = ?", "jianzhu").First(&user).Error; err != nil {
 if errors.Is(err, gorm.ErrRecordFound) {
   // TODO 业务处理查询不到数据的情况
 } 
 if  err != nil {
    // do something  ...
 }
}


其实要注意的是,没查询到结果,也会返回一个Error


gormErrRecordNotFound也好理解,假设根据身份证号查询公民信息,如果是一个无效的身份证ID,那必然无法查询到结果, 其实就是查询不到结果,会返回一个错误。

当然 GORM 提供了一个处理 RecordNotFound 错误的快捷方式,如果发生了多个错误,它将检查每个错误,如果它们中的任何一个是RecordNotFound 错误。

//检查是否返回 RecordNotFound 错误
db.Where("name = ?", "hello world").First(&user).RecordNotFound()
if db.Model(&user).Related(&credit_card).RecordNotFound() {
  // 数据没有找到
}
if err := db.Where("name = ?", "jinzhu").First(&user).Error; gorm.IsRecordNotFoundError(err) {
  // 数据没有找到
}


当一个程序中使用两个不同的数据库时, 重写方法DefaultTableNameHandler()会影响到两个数据库中的表名。其中一个数据库需要设置表前缀时,访问另一个数据库的表也可能会被加上前缀。因为是包级别的方法,整个代码里只能设置一次值。

相关文章
|
4月前
|
SQL 关系型数据库 MySQL
go如何使用SQLX操作MySQL数据库?
sqlx是Go语言中一款流行的第三方数据库操作包,它扩展了Go标准库`database/sql`的功能,极大地简化了数据库操作流程并提供了丰富的数据库交互方法。
|
1月前
|
数据库连接 Go 数据库
Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性
本文探讨了Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性;防御编程则强调在编码时考虑各种错误情况,确保程序健壮性。文章详细介绍了这两种技术在Go语言中的实现方法及其重要性,旨在提升软件质量和可靠性。
32 1
|
1月前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
54 4
|
1月前
|
SQL 关系型数据库 MySQL
go语言中安装数据库驱动
【11月更文挑战第1天】
51 5
|
1月前
|
SQL 关系型数据库 MySQL
go语言中数据库操作
【10月更文挑战第22天】
44 4
|
1月前
|
关系型数据库 MySQL 数据库连接
go语言中打开数据库连接
【11月更文挑战第1天】
31 2
|
1月前
|
Java 数据库连接 数据库
如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面
本文介绍了如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面。通过合理配置初始连接数、最大连接数和空闲连接超时时间,确保系统性能和稳定性。文章还探讨了同步阻塞、异步回调和信号量等并发控制策略,并提供了异常处理的最佳实践。最后,给出了一个简单的连接池示例代码,并推荐使用成熟的连接池框架(如HikariCP、C3P0)以简化开发。
51 2
|
2月前
|
SQL 关系型数据库 MySQL
Go语言项目高效对接SQL数据库:实践技巧与方法
在Go语言项目中,与SQL数据库进行对接是一项基础且重要的任务
90 11
|
3月前
|
SQL 关系型数据库 MySQL
学成在线笔记+踩坑(3)——【内容模块】课程分类查询、课程增改删、课程计划增删改查,统一异常处理+JSR303校验
课程分类查询、课程新增、统一异常处理、统一封装结果类、JSR303校验、修改课程、查询课程计划、新增/修改课程计划
学成在线笔记+踩坑(3)——【内容模块】课程分类查询、课程增改删、课程计划增删改查,统一异常处理+JSR303校验
|
2月前
|
Go
go基础-14.异常处理
go基础-14.异常处理