Mysql sql.Result.LastInsertId()的线程安全性
SQL文档说,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
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
的工作原理。谢谢,我只是想确保我的理解是正确的。