[英]Bulk insert with Golang and Gorm deadlock in concurrency goroutines
我正在嘗試使用Gorm 、 Golang 和 MySQL 批量插入許多記錄。 我的代碼如下所示:
package main
import (
"fmt"
"sync"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type Article struct {
gorm.Model
Code string `gorm:"size:255;uniqueIndex"`
}
func main() {
db, err := gorm.Open(mysql.Open("root@tcp(127.0.0.1:3306)/q_test"), nil)
if err != nil {
panic(err)
}
db.AutoMigrate(&Article{})
// err = db.Exec("TRUNCATE articles").Error
err = db.Exec("DELETE FROM articles").Error
if err != nil {
panic(err)
}
// Build some articles
n := 10000
var articles []Article
for i := 0; i < n; i++ {
article := Article{Code: fmt.Sprintf("code_%d", i)}
articles = append(articles, article)
}
// // Save articles
// err = db.Create(&articles).Error
// if err != nil {
// panic(err)
// }
// Save articles with goroutines
chunkSize := 100
var wg sync.WaitGroup
wg.Add(n / chunkSize)
for i := 0; i < n; i += chunkSize {
go func(i int) {
defer wg.Done()
chunk := articles[i:(i + chunkSize)]
err := db.Create(&chunk).Error
if err != nil {
panic(err)
}
}(i)
}
wg.Wait()
}
當我有時(大約三分之一)運行此代碼時,我收到此錯誤:
panic: Error 1213: Deadlock found when trying to get lock; try restarting transaction
如果我在沒有 goroutines(注釋行)的情況下運行代碼,我不會遇到死鎖。 另外,我注意到如果我刪除code
字段上的唯一索引,死鎖就不會再發生了。 如果我用TRUNCATE articles
替換DELETE FROM articles
語句,死鎖似乎不再發生。 我也用 Postgresql 運行了相同的代碼,它可以工作,沒有死鎖。
知道為什么死鎖只發生在 MySQL 上的唯一索引以及如何避免它?
來源: https://stackoverflow.com/a/20559931/18012302
我認為 mysql 需要時間進行 DELETE 查詢。
嘗試在查詢刪除后添加時間。 time.Sleep
。
err = db.Exec("DELETE FROM articles").Error
if err != nil {
panic(err)
}
time.Sleep(time.Second)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.