Что использовать вместо оператора «lock», когда код выполняется на нескольких машинах? - PullRequest
12 голосов
/ 19 ноября 2011

Оператор lock гарантирует, что один поток не входит в критическую секцию кода, в то время как другой поток находится в критической секции.Однако он не будет работать, если рабочая нагрузка распределена по ферме серверов (например, несколько серверов IIS + балансировщик нагрузки).

Поддерживает ли .NET такой сценарий?
Есть ли какой-либо класс?что можно использовать для управления выполнением критической секции кода потоками, работающими на нескольких машинах?

Если нет, то существует ли какой-либо стандартный метод решения таких проблем?

Этот вопросбыл вдохновлен обсуждением , которое началось здесь , но не ограничивается SharePoint или ASP.NET.

Ответы [ 5 ]

3 голосов
/ 19 ноября 2011

Если у вас есть доступ к централизованному экземпляру SQL Server, вы можете использовать его в качестве координатора распределенной блокировки и управлять блокировками приложений с помощью хранимых процедур sp_getapplock и sp_releaseapplock .

Блокировки приложений (или мьютексы) в SQL Server 2005

3 голосов
/ 19 ноября 2011

Оператор lock полезен только для совместного использования ресурсов в процессе.

Классы Mutex и EventWaitHandle полезны для совместного использования ресурсов несколькими процессами на одном компьютере при использовании имен, которые запускаютсяс "Global\".

Кроме того, вам придется реализовать что-то вне .NET, например, использовать sp_getapplock / sp_releaseapplock в общей базе данных SQL.

1 голос
/ 19 ноября 2011

В настоящее время нет способа реализовать управление многопоточными потоками в ASP.NET. Но это может быть реализовано с помощью архитектуры приложений более высокого уровня. По сути, вам придется реализовать это самостоятельно, используя собственную бизнес-логику.

Архитектурно, вы должны внедрить интерфейс ILockable в ваше решение и иметь классы, которые должны прекратить работу при некоторых условиях для его реализации. Затем используйте набор шлюзов для взаимного управления этими замками.

1 голос
/ 19 ноября 2011

В .Net нет ничего, что могло бы изначально поддерживать межмашинную блокировку.

Стандартный метод состоит в том, чтобы перенести ответственность за такие вещи в одно место, возможно, веб-сервис (не сбалансированный по нагрузке!), Чтобы его можно было вызывать из разных мест. Или, в качестве альтернативы, определение единственного ресурса, доступного для всех (например, базы данных), и использование его в качестве единственного ресурса для получения (например, запись ключа в таблицу блокировок, если ключ существует, блокировка не может быть получена до удаления строки)

1 голос
/ 19 ноября 2011

Поскольку сеть машин в стандартном сценарии не работает с общей памятью, у них нет общего представления об одной переменной, которую можно использовать для синхронизации.Следовательно, вы должны реализовать блокировки с помощью передачи сообщений.

Если вы хотите заблокировать общие ресурсы, вы можете иметь центральный «мастер», регулирующий доступ к этому ресурсу.

Редактировать: Если вам не нужно совместно использовать ресурсы (например, барьер),Вы можете использовать, например, MSMQ для передачи сообщений между машинами.Вероятно, сокеты слишком низкого уровня.

...