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.