使用的版本介绍
错误代码示例
func IdGen() int{
updateIdGenQuery := "UPDATE id_gen SET last_id = last_insert_id(last_id + 1)"
res, err := stam.Exec(updateIdGenQuery)
rowAfffect, rowErr := res.RowAffected()
....//error 处理
getLastId := stam.QueryRow("SELECT last_insert_id() AS last_id")
var lastId int
err = getLastId.Scan(&lastId)
....//error 处理
return lastId
}
错误使用出现的现象
在单机测试过程中没有出现问题,然后开始小规模内部调用测试,这个时候部分同学使用在使用后发现,有些接口调用不成功,马上查看操作记录部分的日志,看到例如无法添加数据,数据已经存在等等...
再通过记录的数据库操作日志来看,sql语句是拼装好了,确实也是返回的错误值...继续排查!
排查错误
经过逐步定位,我们追到了这个idgen生成的地方,这次我们使用方式在上述代码的getLastId那一行添加了个 goroutine
i := 0
for i < 100 {
go func(){
getLastId := stam.QueryRow("SELECT last_insert_id() AS last_id")
var lastId int
getLastId.Scan(&lastId)
println(lastId)
}()
}
添加这个 goroutine 的目的也是为了检测在多个同学一起使用的时候 last_insert_id() 是否是预期的值,结果确实返回的都是非预期的值,这样就算是基本确定了问题在这了。
在通过查找 golang/pkg 的文档中,找到了关于获取最后更新 id 的使用方法, database/sql/#Result
修改代码
后将代码修改为:
res, err := stam.Exec(updateIdgenQuery)
lastId, lastIdErr := res.LastInsertId()
return lastId
