Reputation: 1073
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:
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
Upvotes: 2
Views: 1677
Reputation: 3185
Handling concurrency at the DB level using unique index is the right approach here. Unique index will guarantee uniqueness of countries no matter what.
Don't bother locking the C# code, it will not work as soon as you've got more than 1 server running your app (these days it is likely). Transactions in this case are tricky business so I wouldn't bother.
How to handle those exceptions:
In case your task failed when creating country, catch the exception and retry. If you failed to get the country second time for some reason, log the exception and fail.
Upvotes: 6