2017-08-05 61 views
1

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

问题是:sql.DB里面的这个自动连接管理能否影响sql.Result.LastInsertId()的线程安全?

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

请问第二个INSERT或第一个INSERT的返回行ID?在语句执行时,最后一个插入ID是否被缓存?或者是否导致将单独的语句发送到数据库连接?

回答

2

MySQL客户端 - 服务器协议返回值LAST_INSERT_ID()作为响应数据包执行INSERT操作的查询。通常,客户端API使用SQL API中的方法sql.Result.LastInsertId()将其返回给客户端代码。不需要往返查询。

所以你的问题的答案是“第一个INSERT”。

需要说明的是,MySQL连接在广义上不是线程安全的。相反,它们是连续可重用的资源。多线程客户端环境通过管理串行重用使它们看起来是线程安全的。你已经描述过你的问题如何适用于golang

+0

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