gpt4 book ai didi

mysql - sql.Result.LastInsertId() 的线程安全

转载 作者:IT王子 更新时间:2023-10-29 02:02:54 26 4
gpt4 key购买 nike

SQL 文档说 LAST_INSERT_ID() 在“每个连接”的基础上工作,也就是说,最后一个插入 ID 值不会被执行的 INSERT 语句覆盖通过其他连接。

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

问题是:sql.DB 中的这种自动连接管理会影响 sql.Result.LastInsertId() 的线程安全吗?

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

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

最佳答案

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

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

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

关于mysql - sql.Result.LastInsertId() 的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45520813/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com