首頁  >  文章  >  後端開發  >  MySQL與GORM並發寫入導致錯誤

MySQL與GORM並發寫入導致錯誤

WBOY
WBOY轉載
2024-02-09 10:30:18490瀏覽

MySQL與GORM並發寫入導致錯誤

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() 呼叫包裝在事務中,但沒有幫助。

現在我有以下問題:

  1. mysql 是否適合同時儲存到 1 個表格?
  2. 如果需要事務來完成此任務,應該在哪裡設定?
  3. go sql 驅動程式(錯誤總是發生在 packet.go:1102 中)是否適合執行此操作?
  4. 有人可以幫我嗎(也許可以僱用幾個小時)?

我完全被困住了。如果有幫助的話我也可以分享原始碼。但我首先想知道你猜這是我的程式碼還是一般問題。

解決方法

在每個 goroutine(或線程,對於使用線程的語言)中開啟一個新的資料庫連接。

MySQL 的協定是有狀態的,這意味著如果多個 goroutine 嘗試使用同一個連接,請求和回應會變得非常混亂。

嘗試在 goroutine 之間共用任何其他類型的有狀態協定連線時,您也會遇到相同的問題。

例如ftp也是一個有狀態的協議,這可能更容易理解。用戶端 goroutine 可能會發送類似「取得檔案 x」的訊息,回應應該是一系列包含該檔案內容的訊息。如果另一個 goroutine 在請求/回應正在進行時嘗試使用相同的連接,則兩個客戶端都會感到困惑。第二個 goroutine 將讀取屬於它未要求的檔案的資料包。第一個請求該檔案的 goroutine 會發現它所期望的一些資料包已被讀取。

同樣,MySQL 的協定也不支援多個客戶端 goroutine 共用單一連線。

以上是MySQL與GORM並發寫入導致錯誤的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除