Как я могу автоматически разблокировать таблицы в Oracle через определенное время? - PullRequest
3 голосов
/ 25 января 2012

У меня есть немного кода, который подключается к базе данных Oracle, блокирует таблицу, делает с ней что-то и разблокирует ее.
Я хотел бы знать, что если моя программа зависнет, пока таблица заблокирована,блокировка отключится автоматически.

Есть ли способ настроить Oracle, чтобы сделать это автоматически?

Например, я думаю о чем-то, что скажет: «Если пользователь x поддержалблокировка таблицы y на более чем z секунд, откат транзакции и освобождение таблицы. "

Если это невозможно, могу ли я что-нибудь еще сделать для достижения тех же результатов?Это даже реальная проблема или я просто параноик?

Заранее спасибо.

1 Ответ

11 голосов
/ 25 января 2012

Во-первых, блокировка таблицы не помешает другому сеансу выдавать SELECT операторы для данных.

В сеансе 1, если я заблокирую таблицу

SQL> lock table foo in exclusive mode;

Table(s) Locked.

, я могузатем запустите сеанс 2 и запросите все данные, которые мне нужны

SQL> select * from foo;

      COL1
----------
         1
         1

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

Звучит так, как будто вы пытаетесь реализовать пессимистическую блокировку.В этом случае вместо блокировки таблицы вы делаете SELECT FOR UPDATE, который блокирует конкретную запись, которую вы собираетесь обрабатывать.Пока все другие сеансы также пытаются выполнить SELECT FOR UPDATE (в зависимости от версии Oracle, возможно добавление квалификатора SKIP LOCKED и / или квалификатора WAIT).Это блокирует конкретную строку, которую вы обрабатываете, и позволяет второму сеансу либо выбрать другую строку, либо время ожидания или обнаружить, что нет строк для обработки в зависимости от особенностей реализации.Это не связано с блокировкой таблицы.

Единственный способ снять блокировку - это для сеанса, который получил ее, чтобы освободить ее (обычно путем завершения транзакции), или для сеанса, который получил ее, чтобы быть прекращенным.,Если клиентское приложение все еще работает, но ничего не делает для снятия блокировки или завершения сеанса, блокировка будет удерживаться бесконечно.Администратор БД должен был явно убить сеанс, разрешив откат транзакции и сняв блокировку, чтобы система снова начала двигаться.Если клиентское приложение перестает работать или, по крайней мере, перестает отвечать на запросы (мне все еще неясно, какой именно сценарий сбоя вы обсуждаете), возможно, что включение обнаружения мертвых соединений (DCD) возможно с помощью 'SQLNET.EXPIRE_TIME 'параметр на уровне базы данных заставит базу данных определить, что клиент не отвечает, и автоматически завершить сеанс, откатить транзакцию и снять блокировку.

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

  • Выберите ключ для обработки и какую-то дату, указывающую время последнего обновления строки.
  • Обновление столбца состояния до «обработка»"чтобы другие сеансы не пытались обработать эту же строку.
  • Обработка записи в вашем приложении
  • Когда вы закончите обработку, обновите данные, используя ключ и выбранное вами время.на первом этапе.Если вы обновите 1 строку, вы знаете, что ни один другой сеанс не изменил данные с момента его выбора.Если вы обновите 0 строк, вы знаете, что какой-то другой сеанс изменил данные с тех пор, как вы их выбрали.

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

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