MySQL與GORM的同時寫入問題一直是開發者們頭痛的難題。在高並發的情況下,多個執行緒同時寫入資料庫可能導致資料不一致或錯誤的結果。 php小編百草為你解析這個問題的原因和解決方案,幫助你避免併發寫入帶來的困擾。透過合理的設計與最佳化,可以有效解決MySQL與GORM的並發寫入問題,確保資料的一致性與準確性。
我在 golang 中實作了一個複雜的 csv 導入腳本。 我使用 workerpool 實作。在該工作池中,工作人員運行 1000 個小型 csv 文件,對產品進行分類、標記和品牌化。 它們都寫入同一個資料庫表。到目前為止一切順利。
我面臨的問題是,如果我選擇了 2 個以上的工作人員,進程會隨機崩潰並顯示以下訊息
工作流程是
foreach (csv) { workerPool.submit(csv) } func worker(csv) { foreach (line) { import(line) } } import(line) { product = get(line) product.category = determine_category(product) product.brand = determine_brand(product) save(brand) product.tags = determine_tags(product) //and after all save(product) }
我嘗試將 save() 呼叫包裝在事務中,但沒有幫助。
現在我有以下問題:
我完全被困住了。如果有幫助的話我也可以分享原始碼。但我首先想知道你猜這是我的程式碼還是一般問題。
在每個 goroutine(或線程,對於使用線程的語言)中開啟一個新的資料庫連接。
MySQL 的協定是有狀態的,這意味著如果多個 goroutine 嘗試使用同一個連接,請求和回應會變得非常混亂。
嘗試在 goroutine 之間共用任何其他類型的有狀態協定連線時,您也會遇到相同的問題。
例如ftp也是一個有狀態的協議,這可能更容易理解。用戶端 goroutine 可能會發送類似「取得檔案 x」的訊息,回應應該是一系列包含該檔案內容的訊息。如果另一個 goroutine 在請求/回應正在進行時嘗試使用相同的連接,則兩個客戶端都會感到困惑。第二個 goroutine 將讀取屬於它未要求的檔案的資料包。第一個請求該檔案的 goroutine 會發現它所期望的一些資料包已被讀取。
同樣,MySQL 的協定也不支援多個客戶端 goroutine 共用單一連線。
以上是MySQL與GORM並發寫入導致錯誤的詳細內容。更多資訊請關注PHP中文網其他相關文章!