第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

當太多的 goroutines 查詢 MySQL 時,Go 會出現(xiàn)恐慌

當太多的 goroutines 查詢 MySQL 時,Go 會出現(xiàn)恐慌

Go
Smart貓小萌 2023-01-03 15:34:56
我想運行可與 MySQL 數(shù)據(jù)庫一起使用的單獨 goroutine。我編寫了代碼,如果 goroutine 的數(shù)量少于 1000,它確實有效。但是當我將它更改為 1000 時,Go 開始恐慌。package mainimport (    "database/sql"    _ "github.com/go-sql-driver/mysql"    "time")func routine(db *sql.DB, id int, ch chan<- string) {    update, _ := db.Prepare("SELECT salary FROM users WHERE id = (?)")    defer update.Close()    var salary string    update.QueryRow(id).Scan(&salary)    ch <- salary}func main() {    n := 1000    ch := make(chan string)    list := make([]string, n)    db, _ := sql.Open("mysql", "root:root@/database")    db.SetConnMaxLifetime(time.Minute * 3)    defer db.Close()    for i := 0; i < n; i++ {        go routine(db, 123, ch)    }    for i := 0; i < n; i++ {        list[i] = <-ch    }}這是錯誤panic: runtime error: invalid memory address or nil pointer dereference        panic: runtime error: invalid memory address or nil pointer dereferencegoroutine 948 [running]:database/sql.(*Stmt).Close(0x0)        C:/Program Files/Go/src/database/sql/sql.go:2872 +0x37panic({0x4e8b20, 0x689240})        C:/Program Files/Go/src/runtime/panic.go:838 +0x207database/sql.(*Stmt).QueryContext(0x0, {0x5788e8, 0xc000018050}, {0xc000d5bf60, 0x1, 0x1})        C:/Program Files/Go/src/database/sql/sql.go:2767 +0x82database/sql.(*Stmt).QueryRowContext(0x0?, {0x5788e8?, 0xc000018050?}, {0xc000d5bf60?, 0x27?, 0x0?})        C:/Program Files/Go/src/database/sql/sql.go:2845 +0x2cdatabase/sql.(*Stmt).QueryRow(...)        C:/Program Files/Go/src/database/sql/sql.go:2867main.routine(0x0?, 0x0?, 0x0?)        C:/Users/me/Desktop/go/5. MySQL/main.go:13 +0xfbcreated by main.main        C:/Users/me/Desktop/go/5. MySQL/main.go:28 +0xba我不太確定這個錯誤的原因是什么。該代碼確實適用于較少的 goroutines。此外,我嘗試使用 SQLite 適配器,并且 1000 個 goroutines 工作得很好。但是 1000 在 MySQL 中不是。你能描述一下如何擺脫這些恐慌,讓 1000 甚至 10000 個 goroutines 與數(shù)據(jù)庫一起工作嗎?我的 Go 版本是 1.18.3 windows/amd64github.com/go-sql-driver/mysql - v1.6.0
查看完整描述

2 回答

?
一只名叫tom的貓

TA貢獻1906條經(jīng)驗 獲得超3個贊

檢查你的錯誤,不要忽略它們。例如...

update, _ := db.Prepare("SELECT salary FROM users WHERE id = (?)")

從返回的第二個值db.Prepare是 an error,它將解釋出了什么問題,但您忽略了它。如果prepare失敗,update將被破壞。當您嘗試使用它時,update.QueryRow(id).Scan(&salary)或者defer update.Close()您會感到恐慌。

檢查錯誤并處理它。在這種情況下,打印并返回。

update, err := db.Prepare("SELECT salary FROM users WHERE id = (?)")

if err != nil {

  fmt.Println("db.Prepare failed:", err)

  return

}


// This has to come afterwards else you'll try to close nil.

defer update.Close()

對所有可能返回錯誤的東西執(zhí)行此操作。這意味著db.Prepare、sql.OpenRow.Scan

另請參閱Golang 中的錯誤和異常處理。


注意:MySQL 一次有最大準備語句數(shù)。如果將其設(shè)置得較低,例如 1024,則可能是問題所在。但是錯誤應該告訴你。

注意:一遍又一遍地準備、執(zhí)行和關(guān)閉相同的語句會破壞準備語句的意義。在真實的應用程序中,您只需準備一次語句并將其傳遞給每個 Goroutine。您只會在所有 Goroutine 完成后關(guān)閉該語句。


查看完整回答
反對 回復 2023-01-03
?
陪伴而非守候

TA貢獻1757條經(jīng)驗 獲得超8個贊

鑒于此代碼...

update, _ := db.Prepare("SELECT salary FROM users WHERE id = (?)")
defer update.Close()

db.Prepare返回錯誤時,update將是nil*. 然后您嘗試調(diào)用nil.Close(),產(chǎn)生您的錯誤。

不要盲目地調(diào)用Closenil 對象。


* 這在閱讀文檔時并不明顯,但從實現(xiàn)(最終落在這一行)中可以清楚地看出,當返回的錯誤不是 nil時,*Stmt將是nil。


查看完整回答
反對 回復 2023-01-03
  • 2 回答
  • 0 關(guān)注
  • 131 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號