2015-05-13 6 views
0

Я создаю конечную точку, которая создает нового пользователя. Два запроса одновременно отправляются в конечную точку, будут созданы два пользователя. Как защитить этот критический раздел? Я попытался использовать «[MethodImpl (MethodImplOptions.Synchronized)]», однако он не мешает двум потокам войти в критический раздел.Веб-API критической секции

User user = db.User.Where(u => u.FbId.Equals(userObject.fbid)).FirstOrDefault(); 

     if (user == null)  // critical section 
     { 
      // create user and save it to database 
      db.SaveChanges(); 
     } 
+0

Подсказка: используйте https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx для класса –

+0

Почему это проблема, если ocde входит в этот критический раздел одновременно? –

+0

@LowFlyingPelican http://stackoverflow.com/questions/2223656/what-does-methodimplopions-synchronized-do говорит, что эффект будет идентичным - 2 запроса все равно могут выполняться параллельно, потому что для каждого запроса есть новые контроллеры. Обратите внимание, что утверждение OP о «не предотвращает два потока ...» напрямую не связано с проблемой, и действительно, два потока не смогут вызывать один и тот же метод на * одном и том же объекте * с кодом, указанным OP. –

ответ

0

Если вы назначаете Идентификаторы в коде (плохая идея), а не автоматически на сервере базы данных, но если вы действительно хотели бы иметь критическую секцию, мне это выглядит как ваш код будет работать параллельно и вы не получили бы дубликатов идентификаторов, если бы вы использовали идентификаторы с автоматическим назначением или идентификаторы GUID в качестве идентификаторов:

Каждый запрос из веб-браузера обрабатывается отдельной нитью. Это может быть потоки, выполняемые в рамках одного процесса, или если вы входите в настройки в IIS, вы можете изменить свое приложение для запуска в нескольких процессах.

Если в конечном итоге приложение будет развернуто в облаке Azure, потоки могут не работать даже на одном компьютере. Это имеет значение для использования Lock и альтернативы Global Mutex. Блокировка - это только мьютекс процесса, поэтому он будет работать только с процесса с несколькими потоками. Глобальный мьютекс с запуском в нескольких процессах с несколькими потоками. Но если вы работаете на нескольких географически распределенных машинах в Интернете, вам нужно либо иметь специальную отдельную машину, которая работает с глобальным Mutex, либо использовать чужой прерванный глобальный мьютекс - например, использовать функции блокировки и разблокировки сервера базы данных, например. использование GUID для идентификаторов будет означать отсутствие необходимости в мьютексе, поэтому теоретически для системы огромного объема быстрее.