如果对语言了解不深刻,很容易出现数据的差错,先上代码
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周,遂记录下来,大佬可略~