What is the correct way to lock when using FirstOrCreate?
Hi, I'm using FirstOrCreate in order to perform a pretty standard upsert operation. It seems that its implementation doesn't lock the involved table (at least from what it looks like here), so I was wondering, what is the correct syntax to use to perform locking (specifically for postgres, but it'd be great writing this at a higher abstraction level so that I don't couple the code with the dbms).
Right now I'm using a very hackish workaround that looks like:
func upsertModelWithRetry(name string, retry bool) (*Model, error) {
obj := Model{
Name: name,
}
if res := db.Where(Model{Name: name}).Assign(obj).FirstOrCreate(&obj); res.Error != nil {
if retry && strings.Contains(res.Error.Error(), "duplicate key value violates unique constraint") {
// don't retry a second time in order to avoid recursion
return upsertModelWithRetry(name, false)
} else {
return nil, res.Error
}
}
return &dev, nil
}
func UpsertModel(name string) (*Model, error) {
return upsertModelWithRetry(name, true)
}
The document you expected this should be explained
https://gorm.io/docs/advanced_query.html#FirstOrCreate
Expected answer
Code snippet or link to some related documentation would be great, thanks :)
Comment From: github-actions[bot]
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the Question template, most likely your question already answered https://github.com/go-gorm/gorm/issues or described in the document https://gorm.io ✨ Search Before Asking ✨