Это типичная проблема параллелизма потоков, которая может быть решена несколькими способами, одним из которых является использование простого оператора lock
:
public class StockService
{
private readonly object _availableQtyLock = new object();
public bool UpdateStock(int productId, int purchaseQty)
{
using (var db = new MyEntities())
{
lock (_availableQtyLock)
{
var stock = db.Products.Find(productId);
if (stock.AvailableQty >= purchaseQty) // Condition to check the availablity
{
stock.AvailableQty = stock.AvailableQty - purchaseQty;
db.SaveChanges();
return true;
}
return false;
}
}
}
}
Только один поток может получить эксклюзивные права на блокировку _availableQtyLock
, что означает, что другому потоку придется ждать, пока первый поток снимет блокировку этого объекта.
Примите во внимание, что это самый простой (и, возможно, самый медленный) способ работы с параллелизмом, есть и другие способы синхронизации потоков, например, Monitor
, Semaphore
, быстрый SlimLock
и т. Д. ... Поскольку трудно сказать, какой из них лучше всего подойдет вашим потребностям, вам необходимо провести надлежащее тестирование производительности / стресс-тестов, но я бы посоветовал начать с Простейшие.
Примечание. Как уже упоминалось в комментариях, проблемы с параллелизмом могут решаться и на уровне БД, что на самом деле было бы более подходящим, но если вы не хотите / не можете вносить какие-либо изменения в БД, это может быть способом идти