I've got the following situation:
When using ef6, a business logic function verifies whether a record is already present. The record is added to the database if it doesn't already exist.
comparable to this
if (!product.Skus.Any(s => s.SkuCodeGroup == productInfo.SkuCodeGroup && s.SkuCode == productInfo.SkuCode)) AddProductSku();
I'm calling this business logic function from several threads. What transpires is:
When the function is called twice in a row with the same inputs, it is determined that the record does not exist in both cases. Thus, the identical record is inserted in both cases.
as applicable. On the first occurrence, SaveChanges() is called, and everything is OK. But because the record already exists, the second SaveChanges() produces an exception (there is an unique index on the database).
How can I put this into practice to prevent the exception?
I used a lock to alleviate the problem, however it leads to a bottleneck that I don't want.
The similar problem has come up for us before. If you don't want to use a lock in your code, there isn't really a decent workaround. Make sure there aren't any more ways for new rows to enter the database now or in the future.
If there is a duplicate key error, we just eat the exception after evaluating the exception message. We don't even check to see if the row already exists. We can still accomplish this with SQL Server. As a result, every time we insert, a seek is saved. This strategy serves us and our application well. Depending on what you intend to do after the insert, it might or might not work in every situation.