Что использовать вместо оператора "lock", когда код выполняется на нескольких машинах?

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

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

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

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

5 ответов

Решение

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

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

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам