Спящий сервер или на каждом экземпляре приложения Swing? - PullRequest
0 голосов
/ 27 сентября 2011

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

Это приложение работает на многих компьютерах и нуждается в нескольких вещах:

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

Итак, мой вопрос: где я должен воплощать спящий режим? на каждом экземпляре приложения? или уникальный экземпляр «на стороне сервера» и должен был закодировать механизм протокола (RMI? EHCache распространяется? ...)

Проблема с моделью сервера заключается в том, что мне придется кодировать механизмы для обнаружения закрытия / сбоя приложения.

Спасибо.

1 Ответ

0 голосов
/ 27 сентября 2011

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

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

Часто полезно изучить рекомендуемые шаблоны использования в Java EE, потому что там часто есть скрытый намек. Например, использование EJB позволяет вам рассматривать сервер приложений как шлюз для всех изменений ваших данных. Это дает вам гораздо больший контроль и позволяет перенести на контейнер большую часть работы, которую вам обычно приходится выполнять самостоятельно, например, управление транзакциями. Это также уменьшает потребность в причудливых стратегиях блокировки - по большей части.

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

Плюсы на стороне сервера

  • Не нужно беспокоиться о синхронизации кэша с клиентами
  • Упрощенная обработка транзакций
  • Много существующей инфраструктуры (EJB)
  • Нет прямого доступа к базе данных от вредоносного клиента (например, клиентам не нужно иметь пароли базы данных)

Плюсы на стороне клиента

  • Нет проблем с отсоединенными объектами или объектами передачи данных
  • Упрощенная модель программирования
  • Нет необходимости в причудливом сервере приложений Java EE

PostgreSQL поддерживает явную блокировку строк , выдав SELECT FOR UPDATE для строк, которые вы хотите заблокировать. Это не позволяет другим процессам выдавать UPDATE s или DELETE s для заблокированных вами строк. Тем не менее, это определенный запах кода . PostgreSQL имеет чрезвычайно мощные алгоритмы для обработки параллелизма. В общем, я нахожу людей, желающих явно обрабатывать блокировки в базе данных, обычно не понимают, как базы данных обрабатывают параллелизм , и это почти всегда приводит к боли. Итак, перед тем, как приступить к разработке приложения, требующего явных блокировок, вы должны задать себе несколько вопросов: почему я блокирую данные? Почему меня беспокоит то, что другие процессы одновременно получают доступ к этим строкам? Действительно ли плохо для других процессов обновлять эти строки одновременно? Часто я нахожу, что это указывает на то, что должен существовать другой объект, а строки должны принадлежать определенным пользователям.

Другим важным моментом является то, что блокировки в PostgreSQL действуют только до тех пор, пока транзакция открыта. Долгосрочные транзакции - очень плохая идея, потому что они увеличивают вероятность тупика. Если PostgreSQL обнаружит взаимоблокировку, он выберет одно из соединений и уничтожит его, а шансы очень малы, он убьет то, что вы хотите. Hibernate также не терпит длительных транзакций. Ваш соблазн перенести доступ к базе данных на клиент Swing, очень хорошие шансы, что вы планируете разрешить чрезвычайно длительные транзакции, либо явно, либо прямо с PostgreSQL, либо неявно открывая Hibernate Sessions или EntityManager в течение длительного времени. Это действительно плохие идеи, которые создают много дополнительной памяти и создают проблемы для параллелизма.

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

Из всех этих плохих новостей можно извлечь две хорошие новости:

  • В PostgreSQL имеется удобное средство уведомления , которое можно использовать для синхронизации между различными процессами.Я понятия не имею, как можно использовать это с Hibernate.
  • PostgreSQL не будет сохранять блокировку дольше, чем длится транзакция.Если ваше соединение получает блокировку, а затем отключается, блокировка утрачивается.Вам не нужно беспокоиться об этом.(Даже если это не так, PostgreSQL заметит тупик и убьет одну из транзакций, чтобы позволить работе продолжиться).

В случае, если вы решите разрешить распределенным клиентам прямой доступ к базе данныхпри длительных транзакциях вы можете исследовать использование терракоты для распределенного кэширования 2-го уровня .Это способ сохранить распределенный набор процессов для эффективного совместного использования кэша.

В заключение

Это звучит так, как будто вопрос сформулирован так, как если бы выЯ хочу много явно контролировать базу данных, в то же время используя Hibernate.Это указывает на то, что есть путаница потребностей.Hibernate - слой базы данных абстракция ;Речь идет о сокрытии тех деталей, которые вас активно интересуют. Более того, сам PostgreSQL также является абстракцией, особенно в отношении проблем параллелизма.Я думаю, что вам, вероятно, будет проще реализовать дизайн, который вам, по-видимому, требуется для простого файла с настраиваемым сервером для его поддержки, что является хорошим свидетельством того, что либо ваши потребности очень специализированы и плохо соответствуют технологиям-кандидатам, либоВы неправильно понимаете технологии кандидата.Я вижу гораздо больше недоразумений, чем особые потребности (хотя это и происходит).

Реляционные базы данных не являются просто механизмом постоянства: они также являются точкой интеграции , которая управляет целостность данных .Соответствие требованиям ACID означает, что база данных сама по себе гарантирует, что данные не останутся в поврежденном состоянии несколькими процессами, пишущими одни и те же вещи одновременно.Более того, поскольку данные могут изменяться несколькими процессами, вы должны написать своему программному обеспечению, что данные, которые он только что извлек из базы данных, уже потенциально устарели .Вот почему Hibernate выполняет все свои SELECT внутри транзакции: это единственный способ получить целостный снимок системы, которая в настоящее время претерпевает изменения.

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

В любом случае описанный вами сценарий очень плохо подходит для распределенных вычислений любого рода и особенно плохо подходит для Hibernate.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...