Совместное использование синхронизированного блока Java в кластере или использование глобальной блокировки?

StackOverflow https://stackoverflow.com/questions/1228833

Вопрос

У меня есть код, к которому я хочу разрешить доступ только одному потоку.Я знаю, как это сделать, используя либо synchronized блоки или методы, но будет ли это работать в кластерной среде?

Целевая среда — WebSphere 6.0 с двумя узлами в кластере.

У меня такое ощущение, что synchronized не сработает, поскольку у каждого экземпляра приложения на каждом узле будет своя JVM, верно?

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

База данных — DB2v9, и я обращаюсь к ней напрямую через JNDI (без уровня ORM).

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

Есть ли у кого-нибудь подсказки в этой области?

Спасибо!

Это было полезно?

Решение

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

Правильный способ решения этой проблемы — блокировки на уровне базы данных.Предположительно, у вас есть некая таблица, содержащая версию схемы БД, поэтому вам следует обязательно заблокировать эту таблицу на время процесса запуска/обновления.

Точные вызовы sql/db, вероятно, будут более понятными, если вы укажете тип базы данных (DB2?) и метод доступа (raw sql, jpa и т. д.).

Обновление (4 августа 2009, 14:39):Я предлагаю ЗАМОК СТОЛИКА оператор для некоторой таблицы, содержащей версию # схемы.Это приведет к сериализации доступа к этой таблице, предотвращая одновременное выполнение кода обновления двумя экземплярами.

Другие советы

Да, в этом ты прав синхронизированный блоки не будут работать в кластере.Причина, как вы сказали, в том, что у каждого узла есть своя JVM.

Однако есть способы заставить синхронизированные блоки работать в кластере так же, как они работали бы в среде с одним узлом.Самый простой способ — использовать такой продукт, как Терракота, который будет обеспечивать координацию потоков между различными JVM, чтобы можно было использовать обычные элементы управления параллелизмом во всем кластере.Есть много статей, объясняющих, как это работает, например Введение в OpenTerracotta.

Конечно, есть и другие решения.Во многом это зависит от того, чего вы действительно хотите здесь достичь.Я бы не стал использовать блокировки базы данных для синхронизации, если вам нужно масштабироваться, поскольку БД этого не делает.Но я очень призываю найти готовое решение, потому что возиться с синхронизацией кластера — дело грязное :)

Вы можете использовать сетку данных в памяти, например http://www.hazelcast.com/ и для этого тоже.Это распределенная структура данных, поддерживающая блокировки.

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

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

  1. Добавьте столбец для версии записи/строки.
  2. Просмотрите логику, чтобы проверить, нужно ли обновлять запись.
  3. При обновлении записи убедитесь, что версия записи в БД такая же, как у вас.
  4. Увеличьте версию каждый раз, когда вы пишете в базу данных.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top