Синхронизация данных по всей сети

Мы разработали приложение C# WinForms, работающее на сервере MS SQL. До сегодняшнего дня мы использовали очень простой самодельный OR-Mapper (использующий Reflection) с дешевым механизмом кэширования, реализованным с помощью шаблона singleton. Есть функция «сброса», запускаемая пользователем. Архитектура представляет собой простой двухуровневый (клиент, сервер) и трехуровневый (представление и логика на клиенте, MS SQL в качестве уровня данных на сервере).

Обычно мы загружаем около 300 строк с примерно 30 столбцами, которые меняются довольно часто (и некоторые другие таблицы, которые меняются редко). Различные экземпляры этого приложения, запущенные на разных клиентских компьютерах, имеют одни и те же 300 загруженных строк и изменяют данные в случайной строке. Приложение сразу же обновляет данные в базе данных. Прежде чем они это сделают, целостность проверяется, поэтому пользователь получает обратную связь, если что-то не так. Но для некоторых строк пользователь видит на экране старые значения, ему приходится вручную сбрасывать кеш, когда он хочет быть уверенным, что у него актуальные данные.

Было бы неплохо, если бы приложения сами считали измененные строки. Есть обновления каждые несколько секунд. Но только некоторые из этих обновлений актуальны для других приложений (в зависимости от активного фильтра...)

Решения, которые я имею в виду:

  1. Using a OR-Mapper with a common cache (e.g. NHibernate with a clustered cache)
    • Open questions: Are these L2 caches made for client apps? Can I trigger UI updates when cache changes happen? Other OR-Mapper based solutions?
  2. Implementing another tier using an application server, moving logic to this application server. Run only one instance, which caches the data and sends events on the Logic Object's which notify the other clients of updated data. Don't cache any data on the clients.
  3. Add some kind of data changes notifications on the logic level (broadcast based noticiation...)
    • Open questions: Existing libraries? Load on SQL Server?
  4. Совершенно другое решение?

Я понимаю, что здесь я не получу решения. Просто нужны некоторые мысли об этих решениях (или новых)... Спасибо за любой вклад!


person falstaff    schedule 14.11.2011    source источник


Ответы (3)


Я хотел бы поделиться своим опытом здесь. В аналогичном сценарии, когда все клиенты находились в одной корпоративной локальной сети. Я реализовал UDP-клиент (отправитель/получатель) в своем клиентском приложении, которое транслировало «DataRefreshMessage» по сетевому широковещательному адресу всякий раз, когда клиент обновлял данные. И все другие клиенты обновляли свои представления при получении «DataRefreshMessage».

Я знаю, что UDP ненадежен, но достаточно надежен для моих требований, и мое решение работает отлично.

person ClearLogic    schedule 14.11.2011
comment
Мы использовали Tibco Rendezvous в том же сценарии, который хорош с производительностью, устраняет зависимость от конкретных сетевых протоколов и обеспечивает надежную доставку даже по UDP. - person mikalai; 15.11.2011

Я не использовал это сам, но я считаю, что SQL Server имеет функция зависимости, которая может уведомлять ваше приложение об изменении ранее запрошенных данных.

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

person Dr. Wily's Apprentice    schedule 14.11.2011
comment
Хм, я только что увидел, что оператор SELECT может использовать только подмножество синтаксиса SQL при использовании этой функции... Тем не менее, может сработать для меня, посмотрим :-) msdn.microsoft.com/en-us/library/ms181122.aspx - person falstaff; 15.11.2011

Честно говоря, мне кажется, что вы делаете из кротовины гору. если вы просто загружаете 300 записей, просто время от времени перезагружайте данные из базы данных и не беспокойтесь о кэшировании. Набор данных настолько мал, что в любом случае он будет очень быстрым, и у вас не будет дополнительных сложностей и точек отказа, связанных с использованием распределенного кеша и тому подобного.

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

person iamkrillin    schedule 14.11.2011
comment
Хорошо, я кое-что забыл: в сетке пользователя отображается 300 строк, но это сгруппированное представление фактического набора данных. Фактический набор данных может быть от нескольких сотых до нескольких тысячных записей ... Также, когда я обновляю весь набор данных, скажем, каждые 5 секунд, сам клиент очень занят перерисовкой сетки и такими вещами. Я хотел бы иметь изменения на уровне строки... - person falstaff; 15.11.2011