前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go 数据库操作异常处理

Go 数据库操作异常处理

作者头像
王小明_HIT
发布2022-03-28 16:02:02
7970
发布2022-03-28 16:02:02
举报
文章被收录于专栏:程序员奇点程序员奇点

Go 数据库操作异常处理

插入操作

第一种写法

代码语言:javascript
复制
err := db.Model(&XXX{}).Create(order).Error
 if err != nil {
  logs.CtxError(ctx, "Create XXX failed, err:%v", err.Error())
  return  err
 }

第二种写法

代码语言:javascript
复制
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 操作

更新操作

代码语言:javascript
复制
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

事务处理

代码语言:javascript
复制
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

查询的异常处理

代码语言:javascript
复制
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 错误。

代码语言:javascript
复制
//检查是否返回 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()会影响到两个数据库中的表名。其中一个数据库需要设置表前缀时,访问另一个数据库的表也可能会被加上前缀。因为是包级别的方法,整个代码里只能设置一次值。

参考资料

  • https://gorm.io/docs/transactions.html
  • http://blog.vikazhou.com/2020/02/09/GORM-Problem-Analyze/
  • https://www.topgoer.com/%E6%95%B0%E6%8D%AE%E5%BA%93%E6%93%8D%E4%BD%9C/gorm/%E6%95%99%E7%A8%8B/%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86.html
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-02-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员奇点 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Go 数据库操作异常处理
  • 插入操作
  • 更新操作
  • 事务处理
  • 查询的异常处理
  • 参考资料
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档