Gorm查询not found导致数据丢失的坑

1,736 阅读1分钟

如果对语言了解不深刻,很容易出现数据的差错,先上代码

DB.Where("uuid = ?", uuid).First(&song)

newClickNumber := song.ClickNumber + 1

DB.Model(&song).UpdateColumn("click_number", newClickNumber)

这里我在预想的是,查找到数据库的某一条记录song,就会把它的ClickNumber+1。如果查找不到,按照PHP的ORM的习惯,一般会返回null,而且没有相应的record也不会执行到update(ORM:怪我咯?)

但是!但是!在go里并不会这样,如果查找不到,仍然会返回一个空的struct,也就有可能是

{ 0 0 { } { } { } { } []}

//所以这里仍然会执行
DB.Model(&song).UpdateColumn("click_number", newClickNumber) 
//执行结果就是
UPDATE `songs` SET `click_number` = 1

如果对于生成环境来说,这是一个非常严重的后果!!准备买站票跑路吧.

所以每次查找数据库之前,一定要做好相应的判断,比如

err = DB.Where("uuid = ?", uuid).First(&song).Error

if err!=nil{
    return "xxxx"
}

这个时候如果有err就不要往后执行了

这里也是因为自己粗心大意,没充分了解到Go的数据类型,导致这个bug在线上环境出现了2周,遂记录下来,大佬可略~