Как заблокировать базу данных PostgreSQL через JDBC?
В моем веб-приложении на Java каждый экземпляр при запуске проверяет, обновлена ли база данных через соединение JDBC. Если БД не обновлена, она выполняет процедуру обновления, выполняя сценарии SQL.
Я не могу контролировать, когда экземпляры получают старт. Поэтому мне нужно убедиться, что только один экземпляр одновременно выполняет обновление базы данных. В идеале мне нужно заблокировать всю базу данных, но в соответствии с
http://www.postgresql.org/docs/8.4/static/explicit-locking.html
а также
http://wiki.postgresql.org/wiki/Lock_database
PostgreSQL не поддерживает его (я все еще использую версию 8.4).
Какие еще варианты у меня есть?
2 ответа
Если вы управляете кодом для всех экземпляров, то вы можете создать таблицу в базе данных, где каждый запускаемый экземпляр ищет в этой таблице запись с отметкой времени. Давайте назовем это вашей "блокировкой" записи.
Если процесс обнаруживает, что запись о блокировке не существует, он вставляет запись и обрабатывает необходимые данные.
Если процесс обнаруживает, что запись о блокировке существует, вы можете предположить, что другой процесс создал ее и ничего не делать, ждать ожидания или что-то еще.
С этим дизайном вы эффективно создаете "блокировку" в базе данных для синхронизации ваших процессов. Вы кодируете его, чтобы все процессы знали, что они должны придерживаться логики записи блокировки.
Как только первый процесс, имеющий блокировку, завершил обработку, он должен очистить запись блокировки, чтобы следующий перезапуск вел себя правильно. Вам также необходимо подумать о ситуации, когда блокировка не была снята из-за ошибки сервера или ошибки при выполнении. Как правило, если блокировка старше n
минут вы можете считать его "устаревшим", поэтому удалите его и создайте заново (или просто обновите).
При работе с "блокировочной" записью обязательно используйте уровень изоляции Serializable в подключении к БД, чтобы гарантировать атомарность.
Уровень обслуживания вашего Java-кода может быть реализован в вашей стратегии блокировки до вызова уровня доступа к данным. Не имеет значения, используете ли вы Hibernate или нет, так как это просто логика приложения.
В идеале мне нужно заблокировать всю базу данных.
Действительно ли имеет значение, к чему относится ваша блокировка, если вы эффективно сериализуете доступ? Просто приобретите эксклюзивную блокировку для любого стола или строки в этом отношении.