使用的版本介绍
错误代码示例
- 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