Mysql sql.Result.LastInsertId()的线程安全性

Mysql sql.Result.LastInsertId()的线程安全性,mysql,sql,multithreading,go,Mysql,Sql,Multithreading,Go,SQL文档说,LAST\u INSERT\u ID()是在“每个连接”的基础上工作的,也就是说,通过其他连接执行的INSERT语句不会覆盖LAST INSERT ID值 AFAIU,在Go中(与例如PHP不同),我们不会在每个客户端请求上创建单独的DB连接。相反,我们被告知只创建sql.DB对象的一个实例,它在后台管理一个sql连接池。因此,他们说,不能保证Go程序中的两个连续SQL语句(即使在同一线程中)将通过同一个DB连接执行。因此,情况可能正好相反——两个不同的线程可以在同一个(重用的)D

SQL文档说,
LAST\u INSERT\u ID()
是在“每个连接”的基础上工作的,也就是说,通过其他连接执行的
INSERT
语句不会覆盖LAST INSERT ID值

AFAIU,在Go中(与例如PHP不同),我们不会在每个客户端请求上创建单独的DB连接。相反,我们被告知只创建
sql.DB
对象的一个实例,它在后台管理一个sql连接池。因此,他们说,不能保证Go程序中的两个连续SQL语句(即使在同一线程中)将通过同一个DB连接执行。因此,情况可能正好相反——两个不同的线程可以在同一个(重用的)DB连接上执行两个不同的SQL语句

问题是:
sql.DB
内部的自动连接管理是否会影响
sql.Result.LastInsertId()的线程安全

考虑以下情况:在一个线程中的
INSERT
语句之后,
sql.DB
对象在另一个线程中重用连接,而另一个线程在同一(重用)连接上执行另一个
INSERT
语句。之后,第一个线程查询
sql.Result.LastInsertId()


这将返回第二个插入的行ID还是第一个插入的行ID?最后一个insert ID是在语句执行时缓存的,还是导致向DB连接发送单独的语句

MySQL客户端-服务器协议在执行
插入操作的查询的响应数据包中返回
最后一次插入\u ID()
的值。通常,客户端API使用sql API中的
sql.Result.LastInsertId()
等方法将其返回给客户端代码。不需要往返查询

所以你的问题的答案是“第一次插入。”


很明显,MySQL连接在广义上不是线程安全的。相反,它们是可串行重用的资源。多线程客户端环境通过管理串行重用使它们看起来是线程安全的。在您的问题中,您已经描述了
golang
的工作原理。

谢谢,我只是想确保我的理解是正确的。