Для нашего старшего дизайн-проекта моя группа создает приложение Silverlight, которое использует концепции теории графов и сохраняет данные в базе данных на внутреннем сервере. У нас есть ситуация, когда мы добавляем связь между двумя узлами в графе и после этого запускаем анализ для повторной категоризации наших кластеров узлов. Проблема в том, что эта повторная категоризация довольно сложна и включает в себя несколько запросов и обновлений к базе данных, поэтому, если несколько экземпляров запускаются одновременно, она быстро искажает данные и разбивает (пытаясь повторно вставить уже использованные первичные ключи). По сути это не потокобезопасно, и мы пытаемся сделать его безопасным, и вот где мы терпим неудачу и нуждаемся в помощи:).
Функция создания ссылки выглядит следующим образом:
private Semaphore dblock = new Semaphore(1, 1);
// This function is on our service reference and gets called
// by the client code.
public int addNeed(int nodeOne, int nodeTwo)
{
dblock.WaitOne();
submitNewNeed(createNewNeed(nodeOne, nodeTwo));
verifyClusters(nodeOne, nodeTwo);
dblock.Release();
return 0;
}
private void verifyClusters(int nodeOne, int nodeTwo)
{
// Run analysis of nodeOne and nodeTwo in graph
}
Все копии addNeed должны дождаться окончания первого, прежде чем другой сможет исполниться. Но вместо этого все они, кажется, работают и конфликтуют друг с другом в методе verifyClusters. Одним из решений будет синхронное выполнение вызовов внешнего интерфейса. И на самом деле, когда мы это делаем, все работает нормально, поэтому логика кода не нарушается. Но после запуска наше приложение будет развернуто в рамках бизнес-среды и использовано внутренним ИТ-персоналом (или, по крайней мере, таков план), поэтому у нас возникнет та же проблема. Мы не можем заставить всех клиентов отправлять данные в разное время, поэтому нам действительно нужно синхронизировать их на серверной части. Спасибо за любую помощь, которую вы можете оказать, я был бы рад предоставить любую дополнительную информацию, которая вам может понадобиться!