GORM Playground Link
https://github.com/go-gorm/playground/pull/590
Description
I tried running FirstOrCreate in multiple threads and got the following error output:
2023/04/21 04:12:34 /Users/haozi/playground/main_test.go:30 UNIQUE constraint failed: users.id
[4.397ms] [rows:0] INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`,`age`,`birthday`,`company_id`,`manager_id`,`active`,`id`) VALUES ("2023-04-21 04:12:34.393","2023-04-21 04:12:34.393",NULL,"",0,NULL,NULL,NULL,false,1) RETURNING `id`
main_test.go:31: Failed, got error: UNIQUE constraint failed: users.id
It seems that FirstOrCreate's operation on the database is not atomic and not thread-safe.
Expected: no errors and tests pass.
Comment From: a631807682
All composite APIs are not atomic, you need to lock yourself (in fact, we can't lock, because when you have multiple services, you need distributed locks). Gorm uses Session to provide thread-safe access, I don't see thread-safety from your example, can you reproduce it?
https://gorm.io/docs/v2_release_note.html#Method-Chain-Safety-x2F-Goroutine-Safety
Comment From: devhaozi
All composite APIs are not atomic, you need to lock yourself (in fact, we can't lock, because when you have multiple services, you need distributed locks). Gorm uses Session to provide thread-safe access, I don't see thread-safety from your example, can you reproduce it?
https://gorm.io/docs/v2_release_note.html#Method-Chain-Safety-x2F-Goroutine-Safety
added it, but also fail. https://github.com/go-gorm/playground/pull/590/commits/6415732f70119ccb653741f76606067cb92525e8
Comment From: a631807682
This is still an atomicity-related test, and has nothing to do with thread safety. Thread safety means that no data race will occur. If it's still an atomicity problem, you can lock it yourself
Comment From: devhaozi
This is still an atomicity-related test, and has nothing to do with thread safety. Thread safety means that no data race will occur. If it's still an atomicity problem, you can lock it yourself
Yes, I think the only way to solve this without doing atomic operations is to use a mutex lock.
Comment From: a631807682
This is still an atomicity-related test, and has nothing to do with thread safety. Thread safety means that no data race will occur. If it's still an atomicity problem, you can lock it yourself
Yes, I think the only way to solve this without doing atomic operations is to use a mutex lock.
Yes
Comment From: devhaozi
ok, I will close it.