2017-08-05 158 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