I have a method that searches for an entity on database and attempts to create it if it doesn't exist. As an example:
public async Country FindOrCreate(string name)
{
var country = _context.Countries.FirstOrDefault(p => p.Name == name);
if (country != null)
return country;
country = new Country
{
Name = name
};
_context.Countries.Add(country);
_context.SaveChanges();
return country;
}
The problem is: there are several tasks in background calling FindOrCreate
concurrently. I have prevented duplicates from being inserted by creating an unique index, but the following happens, causing unwanted exceptions:
- Task A tries to find Country and fails
- Task B tries to find Country and fails
- Task A tries to create Country and succeeds
- Task B tries to create Country and fails
What would be the appropriate way of handling these scenarios of concurrency? Should I work with locks using C# code? Or should I set a transaction? TIA