【问题标题】:How to deal with GORM commit/rollback error如何处理 GORM 提交/回滚错误
【发布时间】:2021-03-31 22:53:28
【问题描述】:

我刚刚发现在GORM中,事务提交可能会返回错误,比如:

tx := db.begin()
// do somthing here
err := tx.Commit().Error

回滚时也会出现

tx := db.begin()
// do somthing here
err := tx.Rollback().Error

我想知道这个错误是怎么发生的?

如果发生,GORM 本身是否会执行任何恢复功能来处理待处理的事务?

或者如果回滚或提交返回错误,我是否有必要做点什么?

顺便说一句,GORM 中是否有针对此类事务问题的最佳实践?

【问题讨论】:

    标签: go transactions go-gorm


    【解决方案1】:

    我想知道这个错误是怎么发生的?

    在完全相同的情况下,您可能会从其他数据库调用中得到错误:

    • 网络连接失败
    • 数据库、磁盘或硬件故障
    • 权限问题
    • 命令中的语法错误
    • 数据不一致错误

    对于Begin,您的错误选项有些有限,因为没有(目前)数据可能不一致。但是对于CommitRollback,任何这些错误都是可能的,以及没有要提交的活动事务的情况(因为先前的错误,因为它已经提交,或者因为它已经回滚) .

    如果发生,GORM 本身会做任何恢复功能来处理待处理的事务吗?

    没有。 GORM 不可能,因为它不知道您的应用程序逻辑。与所有类型的所有故障一样,由程序员决定什么是适当的操作。也许你应该重试。也许你应该只重试 N 次。也许您应该忽略失败并像成功一样继续。也许您应该向用户返回一个错误。也许您应该惊慌并崩溃整个程序。 GORM 显然无法知道正确的响应。

    或者如果回滚或提交返回错误,我是否有必要做点什么?

    正如我在上一段中所提到的,只有你能知道这一点。您的应用程序试图做什么?万一出现故障,应该怎么做?

    顺便说一句,GORM 中是否有针对此类事务问题的最佳实践?

    这与 GORM 无关。处理错误的“最佳实践”只是简单地推断错误表示什么,以及在这种情况下您的应用程序应该做什么。

    【讨论】:

    • 之前好像忽略了错误处理。悲伤:/必须按照我的业务逻辑来重写提交和回滚部分。感谢您的详细回复!
    • @Lo1nt:这是每个开发人员最终都很难学到的一课。不过,最好早点学习它:)
    • 是的!对我来说还有很长的路要走:3
    【解决方案2】:

    这里是代码

    func (db *DB) Rollback() *DB {
        if committer, ok := db.Statement.ConnPool.(TxCommitter); ok && committer != nil {
            if !reflect.ValueOf(committer).IsNil() {
                db.AddError(committer.Rollback())
            }
        } else {
            db.AddError(ErrInvalidTransaction)
        }
        return db
    }
    

    所以这只检查tx 实例是否是从Begin() 方法生成的,并且不是普通的*gorm.DB 实例。所以在回滚的情况下,错误检查并不重要(但当然推荐)

    对于.Commit(),您当然应该检查错误,因为提交会在事务期间进行所有数据库交互。因此,如果其中任何一个返回错误.Commit()'s error 将使您可以访问该错误。

    这是文档中使用它的示例 https://gorm.io/docs/transactions.html#A-Specific-Example

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      • 2014-11-20
      • 1970-01-01
      • 2013-05-27
      相关资源
      最近更新 更多