grom 事务 RowsAffected 踩坑记录
最近在编写一段代码的时候碰到了下面的一种情况那就是,在一个事务中插入一条数据,然后插入数据之后判断当前的插入是否生效,写的代码大概如下:
return dao.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {err := tx.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "key"}},DoNothing: true,}).Create(&record).Errorif err != nil {return err}if tx.RowsAffected == 0 {return nil}
})
结果后来发现,这段代码执行到:
if tx.RowsAffected == 0 {return nil
}
就自动结束了, 这里 tx.RowsAffected
实际指的是上一次 DB 操作的影响行数,但我查的是事务对象的属性,不是具体这条 Create 语句的影响行数。
在 GORM 里,RowsAffected 是属于 DB 实例(即 tx.Clauses(...).Create(&record)
返回的那个对象),而不是全局的 tx。
其实修改一下代码实现即可:
dbResult := tx.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "key"}},DoNothing: true,
}).Create(&record)if dbResult.Error != nil {return dbResult.Error
}if dbResult.RowsAffected == 0 {return nil
}