Вопрос архитектуры клиент-сервер - PullRequest
1 голос
/ 16 апреля 2010

Я работаю в системе клиент-сервер и сталкиваюсь с проблемами, когда несколько клиентов выполняют действие одновременно.Мы можем решить эту проблему, заблокировав критическую часть кода, которая гарантирует, что первый клиент выполнит действие до того, как второй клиент войдет в блок кода.Мой вопрос таков: наш сервер также кластеризован, поэтому может существовать несколько экземпляров самого сервера, что создает ту же проблему, что и раньше.Как мы можем решить эту проблему?Спасибо!

Подробнее об этой проблеме: Первый пользователь проверяет, является ли действие действительным, и получает ответ «да».Второй пользователь проверяет, является ли действие допустимым, а также получает ответ «да» до того, как первый пользователь завершит свое действие.Но действие первого пользователя должно сделать действие второго пользователя недействительным.Проблема в том, что проверка происходит почти одновременно для каждого пользователя.

Ответы [ 2 ]

1 голос
/ 16 апреля 2010

Похоже, у вас плохой дизайн. Ваш сервис не должен поддерживать состояние вообще, если это возможно. Таким образом, не будет общего состояния, на которое можно наступить.

Если вы должны поддерживать состояние, то вы должны заблокировать весь доступ к этому общему состоянию. Вы можете использовать ключевое слово «lock» в C # для этого:

private static object _stateLocker = new object();
private static int _someSharedState = 0;

public void SomeAction()
{
    lock (_stateLocker)
    {
        _someSharedState ++;
    }
}

public int GetValue()
{
    lock (_stateLocker)
    {
        return _someSharedState;    }
}
1 голос
/ 16 апреля 2010

Более подробное описание вашей конкретной проблемы было бы полезно для нахождения хорошего решения - однако, похоже, вам нужна какая-то форма межпроцессорной / межсерверной блокировки. В платформе .NET (или API-интерфейсах Win32) нет ничего, что могло бы упростить эту задачу - я боюсь, что вам нужно развернуть собственное решение.

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

Другой вариант, который может у вас быть, - разрешить нескольким процессам одновременно выполнять одно и то же действие, но разрешить выполнение только одному. Это может быть сложно обеспечить, но это дешевле (вычислительно) выполнить дополнительную работу и выбросить ее, чем постоянно проверять, выполняет ли кто-то еще эту работу.

...