Возможно ли автоматически снять блокировку в PostgreSQL?

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

Вопрос

Я тестирую отказоустойчивость системы ActiveMQ, настроенной как JDBC Master / Slave.В этой настройке есть одна база данных postgres и два брокера - один является главным брокером, другой - подчиненным брокером.Способ работы этого механизма заключается в том, что мастер устанавливает эксклюзивную блокировку для таблицы в базе данных.Ведомое устройство также пытается сделать это и ждет, пока блокировка не станет доступной.Если ведущий умирает, блокировка должна быть снята, и ведомый возьмет верх.Однако, если мастер теряет сетевое подключение к базе данных, блокировка никогда не снимается, что приводит к сценарию взаимоблокировки.Что, по-видимому, требуется здесь, так это способ сообщить Postgres автоматически снять блокировку, если она не будет продлена в течение указанного периода времени.Книга шаблонов проектирования POSA 3 называет это шаблоном лизинга.Можно ли заставить Postgres сделать это?Если нет, поддерживают ли это другие поставщики баз данных?

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

Решение

Это не тупиковая ситуация, это проблема с потерянным соединением.

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

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

Всякий раз , когда PostgreSQL обнаруживая потерянное соединение, он автоматически откатывает свою транзакцию.

Чтобы управлять обнаружением потери соединения, вы можете использовать следующее PostgreSQL варианты подключения:

tcp_keepalives_idle (integer)

В системах, поддерживающих TCP_KEEPIDLE параметр сокета, указывает количество секунд между отправкой сохраненных данных при неработающем соединении в противном случае.При нулевом значении используется системное значение по умолчанию.Если TCP_KEEPIDLE не поддерживается, этот параметр должен быть равен нулю.Этот параметр игнорируется для соединений, выполняемых через сокет Unix-домена.

tcp_keepalives_interval (integer)

В системах, поддерживающих TCP_KEEPINTVL параметр сокета, указывает, как долго, в секундах, ждать ответа на keepalive перед повторной передачей.При нулевом значении используется системное значение по умолчанию.Если TCP_KEEPINTVL не поддерживается, этот параметр должен быть равен нулю.Этот параметр игнорируется для соединений, выполняемых через сокет Unix-домена.

tcp_keepalives_count (integer)

В системах, поддерживающих TCP_KEEPCNT параметр сокета, указывает, сколько сохранений может быть потеряно, прежде чем соединение будет считаться разорванным.При нулевом значении используется системное значение по умолчанию.Если TCP_KEEPCNT не поддерживается, этот параметр должен быть равен нулю.Этот параметр игнорируется для соединений, выполняемых через сокет Unix-домена.

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