Oracle ALTER SESSION СОВЕТУЕТ КОМИТЕТ? - PullRequest
1 голос
/ 03 июня 2011

Мое приложение автоматически восстанавливается после сбоев. Я проверяю это следующим образом:

  1. Запустить приложение
  2. В середине обработки убить хост сервера приложений (shutdown -r -f)
  3. При перезагрузке хоста сервер приложений перезагружается (как служба Windows)
  4. Приложение перезапускается
  5. Приложение пытается обработать, но заблокировано незавершенной транзакцией двухфазного принятия в БД Oracle из предыдущего сеанса.
  6. Где-то между 10 и 30 минутами позже БД разрешает предыдущий txn, и обработка продолжается ОК.

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

ALTER SESSION ADVISE COMMIT;

Но он не может дать мне гарантии или подробности о возможности потери данных при этом.

К счастью, рассматриваемое утверждение просто обновляет значение datetime до SYSDATE каждую секунду или около того, поэтому, если произошло какое-либо повреждение данных, оно будет длиться менее 1 секунды, прежде чем оно будет перезаписано.

Но, на мой вопрос. Что именно делает вышеприведенное утверждение? Как Oracle решает проблемы синхронизации данных при их использовании?

1 Ответ

2 голосов
/ 03 июня 2011

Можете ли вы уточнить роль «локальной» и «удаленной» баз данных в вашем сценарии.

Обычно транзакция multi-db выполняет следующее

  1. Запускает транзакцию
  2. Вносит изменения в базу данных
  3. Вносит изменения в другую базу данных
  4. Получает в другой базе данных «обещание зафиксировать»
  5. Местные коммиты
  6. Получает удаленную базу данных для фиксации

В случае сомнений транзакции происходят, если шаг 4 завершен, а затем происходит сбой. Общая практика заключается в резервном копировании удаленной базы данных и подтверждении ее фиксации. Если это так, этап (5) продолжается. Если удаленный компонент транзакции не может быть зафиксирован, локальный компонент откатывается.

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

  1. Сервер приложений берет соединение и запускает транзакцию
  2. Сервер приложений умирает без фиксации
  3. Сервер приложений перезагружается и устанавливает новое соединение с базой данных
  4. Сервер приложений запускает новую транзакцию при новом подключении
  5. Новая транзакция застревает в ожидании блокировки, удерживаемой старым соединением / транзакцией
  6. Через 20 минут прерванное соединение прерывается и откат транзакции
  7. Новая транзакция продолжается

В этом случае решение состоит в том, чтобы быстрее отключить старое соединение с более коротким таймаутом (например, SQLNET_EXPIRE_TIME в sqlnet.ora на сервере) или ручной ALTER SYSTEM KILL SESSION.

...