У меня следующая проблема:
В нашей системе есть продукты, которые только после выпуска могут быть куплены X раз. При покупке центральный алгоритм покупки проверяет, сколько существует заказов и, если ниже X, приступает к покупке.
В псевдоишем C # код:
public class OrderMethods
{
public static Purchase(Product product, Client client)
{
int purchases = /* count order records of this product */;
if(purchases>=MAX_ORDERS) throw PurchaseException();
/* perform purchase by inserting order record in database */
}
}
Проблема в том, что иногда, когда существует высокий спрос на определенный продукт, одновременно происходит много запросов и регистрируется больше, чем MAX_ORDERS. Это происходит примерно раз в год: (.
Какое лучшее решение для решения этой проблемы? Я использую ASP.NET/C#, Ling2SQL и MSSQL. У нас 1000> заказов в день. Важно, чтобы заказы обрабатывались в том порядке, в котором они запрашиваются.
Решения, с которыми я уже столкнулся:
Один глобальный мьютекс?
Один мьютекс на продукт, сохраненный в хеш-таблице с функцией доступа, такой как:
private Mutex GetPurchaseMutex(Guid productId)
{
if (mutexTbl[productId] == null)
{
mutexTbl[productId] = new Mutex();
}
return (Mutex)mutexTbl[productId];
}
Где mutexTbl - это Hashtable. Здесь я не понимаю, как отбросить старые мьютексы хорошим способом.
Использование триггера T-SQL INSERT в таблице Order, которая проверяет, сколько существует заказов:
CREATE TRIGGER Triggers_OrderInsertTrigger ON Orders
ПОСЛЕ ВСТАВКИ
КАК
ЕСЛИ / * проверить, есть ли много заказов * / НАЧАТЬ
RAISERROR («Слишком много заказов», 16, 1);
ROLLBACK TRANSACTION;
ВЕРНУТЬ
END;
Но мне не очень нравится ни одно из этих решений. Как бы вы решили это?